diff --git a/build/jam/ImageRules b/build/jam/ImageRules index 35976def48..2d59eb3a87 100644 --- a/build/jam/ImageRules +++ b/build/jam/ImageRules @@ -1491,30 +1491,24 @@ actions BuildCDBootPPCImage1 bind MAPS { $(RM) $(<) mkdir -p $(HAIKU_OUTPUT_DIR)/cd/ppc - cp $(>) $(HAIKU_OUTPUT_DIR)/cd/ppc/ + mkdir -p $(HAIKU_OUTPUT_DIR)/cd/boot + # CHRP Boot script cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/ppc/bootinfo.txt - cp $(>[1]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.elf - cp $(>[2]) $(HAIKU_OUTPUT_DIR)/cd/ofwboot.xcf - #mkisofs -r -U -chrp-boot -V bootimg -o $(<) $(>[1]) $(>[2-]) - #mkisofs -hfs -r -U -chrp-boot -part -map $(MAPS) -no-desktop \ - # -hfs-volid bootimg -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) - # - $(>[2-]) - #mkisofs -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg \ - # -V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -r -o $(<) $(>[1]) \ - # $(>[2-]) $(HAIKU_OUTPUT_DIR)/cd - #mkisofs -r -U -chrp-boot -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) \ - # $(>[2-]) - #mkisofs -r -U -V bootimg -prep-boot $(>[1]:D=) -o $(<) $(>[1]) $(>[2-]) - # $(HAIKU_OUTPUT_DIR)/cd - # -hfs -hfs-bless . + cp $(>[3]) $(HAIKU_OUTPUT_DIR)/cd/boot/boot.chrp + # Haiku Bootloaders + cp $(>[2]) $(HAIKU_OUTPUT_DIR)/cd/boot/haikuloader.xcf + cp $(>[1]) $(HAIKU_OUTPUT_DIR)/cd/boot/haikuloader.elf + # Extras (readme files, etc) + cp $(>[4]) $(HAIKU_OUTPUT_DIR)/cd/ + mkisofs -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg \ - -V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -prep-boot \ - ppc/$(>[2]:D=) -r -o $(<) $(HAIKU_OUTPUT_DIR)/cd \ + -V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/boot -prep-boot \ + boot/haikuloader.xcf -r -o $(<) $(HAIKU_OUTPUT_DIR)/cd \ || \ genisoimage -v -hfs -part -map $(MAPS) -no-desktop -hfs-volid bootimg \ - -V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/ppc -prep-boot \ - ppc/$(>[2]:D=) -r -o $(<) $(HAIKU_OUTPUT_DIR)/cd - #$(RM) -R $(HAIKU_OUTPUT_DIR)/cd + -V bootimg -hfs-bless $(HAIKU_OUTPUT_DIR)/cd/boot -prep-boot \ + boot/haikuloader.xcf -r -o $(<) $(HAIKU_OUTPUT_DIR)/cd + $(RM) -R $(HAIKU_OUTPUT_DIR)/cd } diff --git a/build/jam/LocaleRules b/build/jam/LocaleRules index 7fcfd693d5..7bd875d4eb 100644 --- a/build/jam/LocaleRules +++ b/build/jam/LocaleRules @@ -10,6 +10,7 @@ rule ExtractCatalogEntries target : sources : signature : regexp local sysHeaders ; local cc ; local defines ; + local includesSeparator ; local localIncludesOption ; local systemIncludesOption ; @@ -22,20 +23,20 @@ rule ExtractCatalogEntries target : sources : signature : regexp if $(PLATFORM) = host { sysHeaders += $(HOST_HDRS) ; defines += $(HOST_DEFINES) ; - + cc = $(HOST_CC) ; if $(USES_BE_API) { sysHeaders += $(HOST_BE_API_HEADERS) ; } - - defines += $(HOST_DEFINES) ; - cc = $(HOST_CC) ; + + includesSeparator = $(HOST_INCLUDES_SEPARATOR) ; localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ; systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ; } else { sysHeaders += $(TARGET_HDRS) ; defines += $(TARGET_DEFINES) ; - defines += $(TARGET_DEFINES) ; cc = $(TARGET_CC) ; + + includesSeparator = $(TARGET_INCLUDES_SEPARATOR) ; localIncludesOption = $(TARGET_LOCAL_INCLUDES_OPTION) ; systemIncludesOption = $(TARGET_SYSTEM_INCLUDES_OPTION) ; } diff --git a/build/jam/images/CDBootPPCImage b/build/jam/images/CDBootPPCImage index d5acf3e81c..d9c2738937 100644 --- a/build/jam/images/CDBootPPCImage +++ b/build/jam/images/CDBootPPCImage @@ -17,7 +17,7 @@ local coffloader = boot_loader_openfirmware_coff ; # OpenFirmware / Mac boot support files: # CHRP script -local chrpboot = ofboot.b ; +local chrpscript = ofboot.chrp ; # HFS creator and application type mapping for mkisofs local hfsmaps = hfs.map ; @@ -25,11 +25,11 @@ local hfsmaps = hfs.map ; # extra files to put on the boot iso local extras = README.html ; -SEARCH on $(chrpboot) $(hfsmaps) $(extras) = [ FDirName $(HAIKU_TOP) data boot_cd ] ; +SEARCH on $(chrpscript) $(hfsmaps) $(extras) = [ FDirName $(HAIKU_TOP) data boot_cd ] ; -BuildCDBootPPCImage $(HAIKU_CD_BOOT_PPC_IMAGE) : $(hfsmaps) : $(elfloader) : $(coffloader) : $(chrpboot) : $(extras) ; +BuildCDBootPPCImage $(HAIKU_CD_BOOT_PPC_IMAGE) : $(hfsmaps) : $(elfloader) : $(coffloader) : $(chrpscript) : $(extras) ; NotFile haiku-boot-cd-ppc ; diff --git a/build/jam/images/HaikuImage b/build/jam/images/HaikuImage index 9b7b7568e3..8fe70b27db 100644 --- a/build/jam/images/HaikuImage +++ b/build/jam/images/HaikuImage @@ -35,7 +35,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures setversion setvolume seq sha1sum sha256sum shar shred shuf shutdown sleep sort spamdbm split stat strace stty su sum sync sysinfo tac tail tcpdump tcptester tee telnet telnetd test timeout top touch - tput tr traceroute translate trash true truncate tsort tty + tr traceroute translate trash true truncate tsort tty uname unchop unexpand unmount uniq unlink unshar unzip unzipsfx updatedb uptime urlwrapper useradd uudecode uuencode vdir version vmstat @@ -45,8 +45,8 @@ SYSTEM_BIN = [ FFilterByBuildFeatures ] ; SYSTEM_APPS = [ FFilterByBuildFeatures - AboutSystem ActivityMonitor BootManager@x86 CharacterMap - CodyCam DeskCalc Devices DiskProbe DiskUsage DriveSetup CDPlayer Debugger + AboutSystem ActivityMonitor BootManager@x86 CDPlayer CharacterMap + CodyCam Debugger DeskCalc Devices DiskProbe DiskUsage DriveSetup Expander GLInfo@x86 Icon-O-Matic Installer LaunchBox Magnify Mail MediaConverter MediaPlayer MidiPlayer NetworkStatus PackageInstaller People PoorMan PowerStatus ProcessController Screenshot ShowImage SoundRecorder @@ -188,6 +188,7 @@ SYSTEM_ADD_ONS_DRIVERS_POWER = [ FFilterByBuildFeatures acpi_button@x86 ] ; SYSTEM_ADD_ONS_BUS_MANAGERS = [ FFilterByBuildFeatures ata@ata pci ps2@x86,x86_64 isa@x86,x86_64 ide@ide scsi config_manager agp_gart@x86 usb firewire@x86 acpi@x86 + virtio ] ; SYSTEM_ADD_ONS_FILE_SYSTEMS = bfs bindfs btrfs cdda exfat ext2 fat iso9660 nfs nfs4 attribute_overlay write_overlay ntfs packagefs reiserfs@x86 udf diff --git a/build/jam/packages/Haiku b/build/jam/packages/Haiku index ee9e3eacc4..3f533cbf9b 100644 --- a/build/jam/packages/Haiku +++ b/build/jam/packages/Haiku @@ -33,8 +33,9 @@ if $(HAIKU_ATA_STACK) = 1 { : generic_ide_pci it8211 legacy_sata silicon_image_3112 ide_isa@x86 ; } -AddFilesToPackage add-ons kernel busses scsi : ahci ; +AddFilesToPackage add-ons kernel busses scsi : ahci virtio_scsi ; AddFilesToPackage add-ons kernel busses usb : uhci ohci ehci ; +AddFilesToPackage add-ons kernel busses virtio : virtio_pci ; AddFilesToPackage add-ons kernel console : vga_text ; AddFilesToPackage add-ons kernel debugger : demangle disasm@x86 hangman @@ -54,6 +55,7 @@ if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 { # drivers AddNewDriversToPackage disk scsi : scsi_cd scsi_disk ; +AddNewDriversToPackage disk virtual : virtio_block ; AddNewDriversToPackage power : enhanced_speedstep@x86 ; AddNewDriversToPackage power : acpi_battery@x86 ; #AddNewDriversToPackage display : display_controls@x86 ; @@ -252,6 +254,7 @@ AddBootModuleSymlinksToPackage ide_isa@x86 uhci ohci ehci scsi_cd scsi_disk usb_disk + virtio virtio_pci virtio_block virtio_scsi efi_gpt intel bfs packagefs diff --git a/build/jam/packages/HaikuDevel b/build/jam/packages/HaikuDevel index 6357ccf0de..7b8670711c 100644 --- a/build/jam/packages/HaikuDevel +++ b/build/jam/packages/HaikuDevel @@ -68,7 +68,6 @@ AddHeaderDirectoryToPackage compatibility bsd : bsd ; AddHeaderDirectoryToPackage compatibility gnu : gnu ; # third party libs headers -AddHeaderDirectoryToPackage libs termcap : 3rdparty ; AddHeaderDirectoryToPackage libs tiff : 3rdparty ; # cpp headers diff --git a/data/boot_cd/hfs.map b/data/boot_cd/hfs.map index 57bba681cf..826a2d2df2 100644 --- a/data/boot_cd/hfs.map +++ b/data/boot_cd/hfs.map @@ -1,7 +1,14 @@ # This mapping is needed to successfully boot and to keep macos # from treating everything like a text file (ugly!) # -# EXTN XLate CREATOR TYPE Comment -.b Raw 'UNIX' 'tbxi' "bootstrap" -boot_loader_openfirmware Raw 'UNIX' 'boot' "bootstrap" -* Raw 'UNIX' 'UNIX' "unix" +# EXTN XLate CREATOR TYPE Comment +.chrp - 'chrp' 'tbxi' "Macintosh Toolbox ROM file" +.elf Raw 'UNIX' 'boot' "ELF Binary" +.xcf Raw 'UNIX' 'boot' "XCOFF Binary" +.htm Ascii 'MOSS' 'TEXT' "HTML File" +.html Ascii 'MOSS' 'TEXT' "HTML File" +.txt Ascii 'ttxt' 'TEXT' "Text File" +.hqx Ascii 'BnHq' 'TEXT' "BinHex file" +.sea Raw 'aust' 'APPL' "Self Expanding Archive" +.sit Raw 'SIT!' 'SITD' "Stuffit Expander file" +* Raw 'UNIX' 'UNIX' "Unix" diff --git a/data/boot_cd/ofboot.b b/data/boot_cd/ofboot.b deleted file mode 100644 index 18aea74a80..0000000000 --- a/data/boot_cd/ofboot.b +++ /dev/null @@ -1,11 +0,0 @@ - - -Haiku Boot Disk - - -Haiku - - -boot cd:,\ppc\boot_loader_openfirmware - - diff --git a/data/boot_cd/ofboot.chrp b/data/boot_cd/ofboot.chrp new file mode 100644 index 0000000000..4e5890a99a --- /dev/null +++ b/data/boot_cd/ofboot.chrp @@ -0,0 +1,180 @@ + + +MacRISC MacRISC3 MacRISC4 + + +Haiku for PowerPC + + +boot cd:,\\haikuloader.elf + + + +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 + + + diff --git a/data/catalogs/add-ons/disk_systems/bfs/pt_BR.catkeys b/data/catalogs/add-ons/disk_systems/bfs/pt_BR.catkeys index 93230199dc..8b9f55bd46 100644 --- a/data/catalogs/add-ons/disk_systems/bfs/pt_BR.catkeys +++ b/data/catalogs/add-ons/disk_systems/bfs/pt_BR.catkeys @@ -1,8 +1,8 @@ 1 portuguese (brazil) x-vnd.Haiku-BFSAddOn 1074880496 Enable query support BFS_Initialize_Parameter Habilitar suporte a consultas 2048 (Recommended) BFS_Initialize_Parameter 2048 (Recomendado) -8192 (Mostly large files) BFS_Initialize_Parameter 8192 (Arquivos grandes em maioria) -Disabling query support may speed up certain file system operations, but should only be used if one is absolutely certain that one will not need queries.\nAny volume that is intended for booting Haiku must have query support enabled. BFS_Initialize_Parameter Disabilitar o suporte a consultas pode aumentar a velocidade de certas operações do sistema, mas somente deve ser utilizado se estiver absolutamente certo de que não irá precisar de consultas.\nQualquer volume que for necessário para inicializar o Haiku precisa ter suporte a consultas habilitado. -1024 (Mostly small files) BFS_Initialize_Parameter 1024 (Arquivos pequenos em maioria) +8192 (Mostly large files) BFS_Initialize_Parameter 8192 (Majoritariamente arquivos grandes) +Disabling query support may speed up certain file system operations, but should only be used if one is absolutely certain that one will not need queries.\nAny volume that is intended for booting Haiku must have query support enabled. BFS_Initialize_Parameter Desabilitar o suporte a consultas pode aumentar a velocidade de certas operações do sistema de arquivos, entretanto deveria ser utilizado somente se estiver absolutamente certo de que não necessitará de consultas.\nQualquer volume que for necessário para inicializar o Haiku deve obrigatoriamente ter o suporte a consultas habilitado. +1024 (Mostly small files) BFS_Initialize_Parameter 1024 (Na maioria arquivos pequenos) Blocksize: BFS_Initialize_Parameter Tamanho do bloco: Name: BFS_Initialize_Parameter Nome: diff --git a/data/catalogs/add-ons/input_server/devices/keyboard/pt_BR.catkeys b/data/catalogs/add-ons/input_server/devices/keyboard/pt_BR.catkeys index e345e9ab9b..36e083d833 100644 --- a/data/catalogs/add-ons/input_server/devices/keyboard/pt_BR.catkeys +++ b/data/catalogs/add-ons/input_server/devices/keyboard/pt_BR.catkeys @@ -1,8 +1,8 @@ 1 portuguese (brazil) x-vnd.Haiku-KeyboardInputServerDevice 2536418998 -Kill application Team monitor Matar aplicação +Kill application Team monitor Matar aplicativo Quit application Team monitor Fechar aplicativo Select an application from the list above and click one of the buttons 'Kill application' and 'Quit application' in order to close it.\n\nHold CONTROL+ALT+DELETE for %ld seconds to reboot. Team monitor Selecione um aplicativo da lista acima e clique um dos botões 'Matar aplicativo' e 'Fechar aplicativo' de maneira a fechá-lo.\n\nPressione CONTROL+ALT+DELETE por %ld segundos para reiniciar. -If the application will not quit you may have to kill it. Team monitor Se a aplicação não fechar, você deve matá-la. +If the application will not quit you may have to kill it. Team monitor Se o aplicativo não fechar, você deve matá-lo. Force reboot Team monitor Forçar a reinicialização Team monitor Team monitor Monitor de equipe (This team is a system component) Team monitor (Esta equipe é um componente do sistema) diff --git a/data/catalogs/add-ons/media/media-add-ons/multi_audio/be.catkeys b/data/catalogs/add-ons/media/media-add-ons/multi_audio/be.catkeys index 5497b93946..c1161e0f17 100644 --- a/data/catalogs/add-ons/media/media-add-ons/multi_audio/be.catkeys +++ b/data/catalogs/add-ons/media/media-add-ons/multi_audio/be.catkeys @@ -18,7 +18,7 @@ Output treble MultiAudio Выхад высокіх Mono mix MultiAudio Моно мікс General MultiAudio Агульны Input & Output MultiAudio Выхад і Ўваход -Enhanced Setup MultiAudio Спец. Наладкі +Enhanced Setup MultiAudio Спецыяльныя Наладкі Stereo mix MultiAudio Стэрэа мікс Output 3D depth MultiAudio Выхад глыбіня 3D Volume MultiAudio Гучнасьць diff --git a/data/catalogs/add-ons/screen_savers/glife/ja.catkeys b/data/catalogs/add-ons/screen_savers/glife/ja.catkeys index bd7d5f7044..a6e64cd395 100644 --- a/data/catalogs/add-ons/screen_savers/glife/ja.catkeys +++ b/data/catalogs/add-ons/screen_savers/glife/ja.catkeys @@ -10,6 +10,6 @@ Grid Width: %li GLife ScreenSaver グリッドの幅: %li Grid Height: %li GLife ScreenSaver グリッドの高さ: %li Grid Life Delay: GLife ScreenSaver グリッドの生存猶予: OpenGL \"Game of Life\" GLife ScreenSaver OpenGL \"ライフゲーム\" -Grid Life Delay: %s GLife ScreenSaver グリッドの生存猶予: %s +Grid Life Delay: %s GLife ScreenSaver グリッドが変化するまでの時間: %s Grid Border: GLife ScreenSaver グリッドの境界: by Aaron Hill GLife ScreenSaver Aaron Hill 作 diff --git a/data/catalogs/add-ons/translators/tiff/be.catkeys b/data/catalogs/add-ons/translators/tiff/be.catkeys index 39401e1eed..c89f4eeecb 100644 --- a/data/catalogs/add-ons/translators/tiff/be.catkeys +++ b/data/catalogs/add-ons/translators/tiff/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-TIFFTranslator 237855326 +1 belarusian x-vnd.Haiku-TIFFTranslator 1930083198 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: немагчыма пераключыць каталог\n TIFF image TIFFTranslator Выява TIFF @@ -10,7 +10,7 @@ TIFFTranslator Settings TIFFTranslator Наладкі канвертара вы TIFF image translator TIFFTranslator Канвертар выяваў TIFF RLE (Packbits) TIFFView RLE (Packbits) TIFF Settings TIFFMain Наладкі TIFF +Use compression: TIFFView Сціскаць: identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: некарэктны індэкс дакументу\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Версія %d.%d.%d %s -Use Compression: TIFFView Запакаваць: diff --git a/data/catalogs/add-ons/translators/tiff/de.catkeys b/data/catalogs/add-ons/translators/tiff/de.catkeys index 393ba1af76..6447599cbe 100644 --- a/data/catalogs/add-ons/translators/tiff/de.catkeys +++ b/data/catalogs/add-ons/translators/tiff/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-TIFFTranslator 237855326 +1 german x-vnd.Haiku-TIFFTranslator 1930083198 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: Ordner konnte nicht gesetzt werden\n TIFF image TIFFTranslator TIFF-Bild @@ -10,7 +10,7 @@ TIFFTranslator Settings TIFFTranslator TIFFTranslator-Einstellungen TIFF image translator TIFFTranslator TIFF-Bild-Translator RLE (Packbits) TIFFView RLE (Packbits) TIFF Settings TIFFMain TIFF-Einstellungen +Use compression: TIFFView Komprimierung: identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: ungültiger Dokument-Index\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Version %d.%d.%d %s -Use Compression: TIFFView Komprimierung: diff --git a/data/catalogs/add-ons/translators/tiff/el.catkeys b/data/catalogs/add-ons/translators/tiff/el.catkeys index 9c229341c6..38da77d6bd 100644 --- a/data/catalogs/add-ons/translators/tiff/el.catkeys +++ b/data/catalogs/add-ons/translators/tiff/el.catkeys @@ -1,4 +1,4 @@ -1 greek, modern (1453-) x-vnd.Haiku-TIFFTranslator 237855326 +1 greek, modern (1453-) x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: αδυναμία ορισμού του καταλόγου\n TIFF image TIFFTranslator TIFF εικόνα @@ -13,4 +13,3 @@ TIFF Settings TIFFMain TIFF Ρυθμίσεις identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: λανθασμένο έγγραφο ευρετηρίου\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Έκδοση %d.%d.%d %s -Use Compression: TIFFView Χρήση συμπίεσης: diff --git a/data/catalogs/add-ons/translators/tiff/fi.catkeys b/data/catalogs/add-ons/translators/tiff/fi.catkeys index 46a6393dfa..e6682fa801 100644 --- a/data/catalogs/add-ons/translators/tiff/fi.catkeys +++ b/data/catalogs/add-ons/translators/tiff/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-TIFFTranslator 237855326 +1 finnish x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: ei voitu asettaa hakemistoa\n TIFF image TIFFTranslator TIFF-kuva @@ -13,4 +13,3 @@ TIFF Settings TIFFMain TIFF-asetukset identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: virheellinen asiakirjahakemisto\n ZIP (Deflate) TIFFView ZIP (Kutista) Version %d.%d.%d %s TIFFView Versio %d.%d.%d %s -Use Compression: TIFFView Käyttäjätiivistys: diff --git a/data/catalogs/add-ons/translators/tiff/fr.catkeys b/data/catalogs/add-ons/translators/tiff/fr.catkeys index 00dc9e2993..abe2b66c5f 100644 --- a/data/catalogs/add-ons/translators/tiff/fr.catkeys +++ b/data/catalogs/add-ons/translators/tiff/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-TIFFTranslator 237855326 +1 french x-vnd.Haiku-TIFFTranslator 1930083198 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identification de l'entête TIFF : impossible de déterminer l'annuaire\n TIFF image TIFFTranslator Image TIFF @@ -10,7 +10,7 @@ TIFFTranslator Settings TIFFTranslator Réglages du traducteur TIFF TIFF image translator TIFFTranslator Traducteur d'images TIFF RLE (Packbits) TIFFView RLE (bits empaqueté) TIFF Settings TIFFMain Réglages TIFF +Use compression: TIFFView Méthode de compression : identify_tiff_header: invalid document index\n TIFFTranslator identification de l'entête TIFF : index de document invalide\n ZIP (Deflate) TIFFView ZIP (Compression) Version %d.%d.%d %s TIFFView Version %d.%d.%d %s -Use Compression: TIFFView Utiliser la compression : diff --git a/data/catalogs/add-ons/translators/tiff/hu.catkeys b/data/catalogs/add-ons/translators/tiff/hu.catkeys index 39f3453080..0fca8daf08 100644 --- a/data/catalogs/add-ons/translators/tiff/hu.catkeys +++ b/data/catalogs/add-ons/translators/tiff/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Haiku-TIFFTranslator 237855326 +1 hungarian x-vnd.Haiku-TIFFTranslator 1930083198 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: nem sikerült a mappát beállítani\n TIFF image TIFFTranslator TIFF kép @@ -10,7 +10,7 @@ TIFFTranslator Settings TIFFTranslator TIFFÉrtelmező beállítások TIFF image translator TIFFTranslator TIFF kép értelmező RLE (Packbits) TIFFView RLE TIFF Settings TIFFMain TIFF beállítások +Use compression: TIFFView Tömörítés módja: identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: érvénytelen dokumentumindex\n ZIP (Deflate) TIFFView ZIP Version %d.%d.%d %s TIFFView %d.%d.%d %s verzió -Use Compression: TIFFView Tömörítés módja: diff --git a/data/catalogs/add-ons/translators/tiff/ja.catkeys b/data/catalogs/add-ons/translators/tiff/ja.catkeys index f52a3dae51..96f1b35599 100644 --- a/data/catalogs/add-ons/translators/tiff/ja.catkeys +++ b/data/catalogs/add-ons/translators/tiff/ja.catkeys @@ -1,4 +1,4 @@ -1 japanese x-vnd.Haiku-TIFFTranslator 237855326 +1 japanese x-vnd.Haiku-TIFFTranslator 1930083198 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: couldn't set directory\n TIFF image TIFFTranslator TIFF イメージ @@ -10,7 +10,7 @@ TIFFTranslator Settings TIFFTranslator TIFF トランスレーター設定 TIFF image translator TIFFTranslator TIFF イメージトランスレーター RLE (Packbits) TIFFView RLE (Packbits) TIFF Settings TIFFMain TIFF 設定 +Use compression: TIFFView 圧縮方法: identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: invalid document index\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView バージョン %d.%d.%d %s -Use Compression: TIFFView 圧縮方法: diff --git a/data/catalogs/add-ons/translators/tiff/lt.catkeys b/data/catalogs/add-ons/translators/tiff/lt.catkeys index 2d66de3099..d017a629d7 100644 --- a/data/catalogs/add-ons/translators/tiff/lt.catkeys +++ b/data/catalogs/add-ons/translators/tiff/lt.catkeys @@ -1,4 +1,4 @@ -1 lithuanian x-vnd.Haiku-TIFFTranslator 237855326 +1 lithuanian x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: nepavyko nustatyti katalogo\n TIFF image TIFFTranslator TIFF paveikslas @@ -13,4 +13,3 @@ TIFF Settings TIFFMain TIFF nuostatos identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: negalimas dokumento indeksas\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Versija %d.%d.%d %s -Use Compression: TIFFView Naudoti glaudinimą: diff --git a/data/catalogs/add-ons/translators/tiff/nl.catkeys b/data/catalogs/add-ons/translators/tiff/nl.catkeys index 0ac95f4ce6..e69e93a1a6 100644 --- a/data/catalogs/add-ons/translators/tiff/nl.catkeys +++ b/data/catalogs/add-ons/translators/tiff/nl.catkeys @@ -1,4 +1,4 @@ -1 dutch; flemish x-vnd.Haiku-TIFFTranslator 237855326 +1 dutch; flemish x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: kan directory niet plaatsen\n TIFF image TIFFTranslator TIFF afbeelding @@ -13,4 +13,3 @@ TIFF Settings TIFFMain TIFF Instellingen identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: ongeldige documentindex\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Versie %d.%d.%d %s -Use Compression: TIFFView Gebruik compressie: diff --git a/data/catalogs/add-ons/translators/tiff/pl.catkeys b/data/catalogs/add-ons/translators/tiff/pl.catkeys index a1367d80cd..c3cc0b0ca8 100644 --- a/data/catalogs/add-ons/translators/tiff/pl.catkeys +++ b/data/catalogs/add-ons/translators/tiff/pl.catkeys @@ -1,4 +1,4 @@ -1 polish x-vnd.Haiku-TIFFTranslator 237855326 +1 polish x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: nie można ustawić katalogu\n TIFF image TIFFTranslator Obraz TIFF @@ -13,4 +13,3 @@ TIFF Settings TIFFMain Ustawienia TIFF identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: błędny indeks dokumentu\n ZIP (Deflate) TIFFView ZIP (deflate) Version %d.%d.%d %s TIFFView Wersja %d.%d.%d %s -Use Compression: TIFFView Użyj kompresji: diff --git a/data/catalogs/add-ons/translators/tiff/pt_BR.catkeys b/data/catalogs/add-ons/translators/tiff/pt_BR.catkeys index f82635133a..f37066b35d 100644 --- a/data/catalogs/add-ons/translators/tiff/pt_BR.catkeys +++ b/data/catalogs/add-ons/translators/tiff/pt_BR.catkeys @@ -1,4 +1,4 @@ -1 portuguese (brazil) x-vnd.Haiku-TIFFTranslator 237855326 +1 portuguese (brazil) x-vnd.Haiku-TIFFTranslator 1930083198 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: não foi possível definir diretório\n TIFF image TIFFTranslator imagem TIFF @@ -10,7 +10,7 @@ TIFFTranslator Settings TIFFTranslator Definições do Tradutor TIFF TIFF image translator TIFFTranslator tradutor de imagem TIFF RLE (Packbits) TIFFView RLE (Pacote de bits) TIFF Settings TIFFMain Definições de TIFF +Use compression: TIFFView Usar compressão: identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: indexação de documento inválida\n ZIP (Deflate) TIFFView ZIP (Extrair) Version %d.%d.%d %s TIFFView Versão %d.%d.%d %s -Use Compression: TIFFView Usar Compressão: diff --git a/data/catalogs/add-ons/translators/tiff/ro.catkeys b/data/catalogs/add-ons/translators/tiff/ro.catkeys index 884f2d1c68..5aece92abb 100644 --- a/data/catalogs/add-ons/translators/tiff/ro.catkeys +++ b/data/catalogs/add-ons/translators/tiff/ro.catkeys @@ -1,4 +1,4 @@ -1 romanian x-vnd.Haiku-TIFFTranslator 237855326 +1 romanian x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: nu s-a putut configura dosarul\n TIFF image TIFFTranslator Imagine TIFF @@ -13,4 +13,3 @@ TIFF Settings TIFFMain Configurări TIFF identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: indice de document nevalid\n ZIP (Deflate) TIFFView ZIP (Dezumflare) Version %d.%d.%d %s TIFFView Versiune %d.%d.%d %s -Use Compression: TIFFView Utilizează compresia: diff --git a/data/catalogs/add-ons/translators/tiff/ru.catkeys b/data/catalogs/add-ons/translators/tiff/ru.catkeys index f1955e6a5f..993355fb07 100644 --- a/data/catalogs/add-ons/translators/tiff/ru.catkeys +++ b/data/catalogs/add-ons/translators/tiff/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Haiku-TIFFTranslator 237855326 +1 russian x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: не удалось установить каталог\n TIFF image TIFFTranslator TIFF изображение @@ -13,4 +13,3 @@ TIFF Settings TIFFMain Настройки TIFF транслятора identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: неверный индекс документа\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Версия %d.%d.%d %s -Use Compression: TIFFView Использовать сжатие: diff --git a/data/catalogs/add-ons/translators/tiff/sk.catkeys b/data/catalogs/add-ons/translators/tiff/sk.catkeys index 8501457ab0..fb56a75076 100644 --- a/data/catalogs/add-ons/translators/tiff/sk.catkeys +++ b/data/catalogs/add-ons/translators/tiff/sk.catkeys @@ -1,4 +1,4 @@ -1 slovak x-vnd.Haiku-TIFFTranslator 237855326 +1 slovak x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: nepodarilo sa nastaviť adresár\n TIFF image TIFFTranslator Obrázok TIFF @@ -13,4 +13,3 @@ TIFF Settings TIFFMain Nastavenia TIFF identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: neplatný index dokumentu\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Verzia %d.%d.%d %s -Use Compression: TIFFView Použiť kompresiu: diff --git a/data/catalogs/add-ons/translators/tiff/sv.catkeys b/data/catalogs/add-ons/translators/tiff/sv.catkeys index adb8783520..11bf152408 100644 --- a/data/catalogs/add-ons/translators/tiff/sv.catkeys +++ b/data/catalogs/add-ons/translators/tiff/sv.catkeys @@ -1,4 +1,4 @@ -1 swedish x-vnd.Haiku-TIFFTranslator 237855326 +1 swedish x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header: kunde inte ange mapp\n TIFF image TIFFTranslator TIFF-bild @@ -13,4 +13,3 @@ TIFF Settings TIFFMain TIFF-inställningar identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header: felaktigt dokumentindex\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Version %d.%d.%d %s -Use Compression: TIFFView Använd komprimering: diff --git a/data/catalogs/add-ons/translators/tiff/uk.catkeys b/data/catalogs/add-ons/translators/tiff/uk.catkeys index 0976f14cb7..fe9b3ecd67 100644 --- a/data/catalogs/add-ons/translators/tiff/uk.catkeys +++ b/data/catalogs/add-ons/translators/tiff/uk.catkeys @@ -1,4 +1,4 @@ -1 ukrainian x-vnd.Haiku-TIFFTranslator 237855326 +1 ukrainian x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator iВизначення заголовка tiff: неможливо встановити каталог\n TIFF image TIFFTranslator Зображення TIFF @@ -13,4 +13,3 @@ TIFF Settings TIFFMain Настройки TIFF identify_tiff_header: invalid document index\n TIFFTranslator Визначення заголовка tiff: неправильний показник документу\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView Версія %d.%d.%d %s -Use Compression: TIFFView Використати зтиск: diff --git a/data/catalogs/add-ons/translators/tiff/zh_Hans.catkeys b/data/catalogs/add-ons/translators/tiff/zh_Hans.catkeys index e94181f349..cd9fabc984 100644 --- a/data/catalogs/add-ons/translators/tiff/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/tiff/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-TIFFTranslator 237855326 +1 english x-vnd.Haiku-TIFFTranslator 1624888114 LZW TIFFView LZW identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header:无法设置目录\n TIFF image TIFFTranslator TIFF 图像 @@ -13,4 +13,3 @@ TIFF Settings TIFFMain TIFF 设置 identify_tiff_header: invalid document index\n TIFFTranslator identify_tiff_header:无效文档索引\n ZIP (Deflate) TIFFView ZIP (Deflate) Version %d.%d.%d %s TIFFView 版本 %d.%d.%d,%s -Use Compression: TIFFView 使用压缩: diff --git a/data/catalogs/apps/bootmanager/de.catkeys b/data/catalogs/apps/bootmanager/de.catkeys index 0285647091..311791c2ac 100644 --- a/data/catalogs/apps/bootmanager/de.catkeys +++ b/data/catalogs/apps/bootmanager/de.catkeys @@ -26,7 +26,7 @@ After one second DefaultPartitionPage Nach einer Sekunde The partition table of the first hard disk is not compatible with Boot Manager.\nBoot Manager needs 2 KB available space before the first partition. BootManagerController Die Partitionstabelle auf der ersten Festplatte ist nicht mit dem Bootmenü kompatibel.\nDas Bootmenü benötigt 2 KiB freien Speicher vor der ersten Partition. The following partitions were detected. Please check the box next to the partitions to be included in the boot menu. You can also set the names of the partitions as you would like them to appear in the boot menu. PartitionsPage Die folgenden Partitionen wurden erkannt. Nun müssen die Partitionen ausgewählt werden, die im Bootmenü erscheinen sollen. Außerdem können sie so benannt werden, wie sie später im Menü erscheinen sollen. After one minute DefaultPartitionPage Nach einer Minute -The Master Boot Record of the boot device (%DISK) has been successfully restored from %FILE. BootManagerController Der Master-Boot-Record des Bootlaufwerks (%s) wurde erfolgreich aus der Sicherungsdatei %s wiederhergestellt. +The Master Boot Record of the boot device (%DISK) has been successfully restored from %FILE. BootManagerController Der Master-Boot-Record des Bootlaufwerks (%DISK) wurde erfolgreich aus der Sicherungsdatei %FILE wiederhergestellt. Write boot menu BootManagerController Button Bootmenü schreiben The Master Boot Record could not be restored! BootManagerController Der Master-Boot-Record konnte nicht wiederhergestellt werden! Uninstall DrivesPage Button Entfernen diff --git a/data/catalogs/apps/deskbar/be.catkeys b/data/catalogs/apps/deskbar/be.catkeys index 7c21144ad2..8dfe58a47e 100644 --- a/data/catalogs/apps/deskbar/be.catkeys +++ b/data/catalogs/apps/deskbar/be.catkeys @@ -1,16 +1,19 @@ -1 belarusian x-vnd.Be-TSKB 1042823442 +1 belarusian x-vnd.Be-TSKB 2335730970 Power off DeskbarMenu Выключыць +Sort applications by name PreferencesWindow Сартаваць прагамы па назвах Suspend DeskbarMenu Прыпыніць Hide clock TimeView Схаваць гадзіннік Applications PreferencesWindow Праграмы Time preferences… TimeView Наладкі Часу… About Haiku DeskbarMenu Пра Haiku +Edit in Tracker… PreferencesWindow Рэдагаваць у Тракеры… Recent documents: PreferencesWindow Нядаўнія дакументы: Recent applications DeskbarMenu Нядаўнія праграмы Applications B_USER_DESKBAR_DIRECTORY/Applications Праграмы Find… DeskbarMenu Знайсці… Show clock Tray Паказаць гадзіннік Window PreferencesWindow Акно +Defaults PreferencesWindow Прадвызначаныя Menu PreferencesWindow Меню Recent documents DeskbarMenu Нядаўнія дакументы Auto-hide PreferencesWindow Схаваць аўтаматычна @@ -28,6 +31,7 @@ Restart Tracker DeskbarMenu Перазапусціць Tracker Close all WindowMenu Закрыць усё Deskbar preferences PreferencesWindow Наладкі Deskbar Mount DeskbarMenu Прымацаваць +Revert PreferencesWindow Вярнуць Small PreferencesWindow Малы Recent applications: PreferencesWindow Нядаўнія праграмы: Shutdown… DeskbarMenu Спыніць… diff --git a/data/catalogs/apps/drivesetup/be.catkeys b/data/catalogs/apps/drivesetup/be.catkeys index 0ffb736bc2..993b97c0f6 100644 --- a/data/catalogs/apps/drivesetup/be.catkeys +++ b/data/catalogs/apps/drivesetup/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-DriveSetup 1752326393 +1 belarusian x-vnd.Haiku-DriveSetup 3775412465 DriveSetup System name Рэдыктар дыскаў Cancel AbstractParametersPanel Адмяніць Delete MainWindow Выдаліць @@ -8,7 +8,7 @@ OK MainWindow ОК Could not aquire partitioning information. MainWindow Не ўдалося атрымаць інфармацыю аб падзелах. There's no space on the partition where a child partition could be created. MainWindow Няма мечца на падзеле для стварэння даччынага падзела. Initialize InitializeParametersPanel Ініцыялізіраваць -OK AbstractParametersPanel ОК +OK AbstractParametersPanel Добра PartitionList <пуста> Unable to find the selected partition by ID. MainWindow Не ўдалося знайсці абраны падзел па ID. Select a partition from the list below. DiskView Абярыце падзел са спісу нішэй. @@ -18,6 +18,7 @@ The selected disk is read-only. MainWindow Абраны дыск толькі Are you sure you want to format the partition \"%s\"? You will be asked again before changes are written to the disk. MainWindow Вы упэўнены, што жадаеце фарматаваць падзел \"%s\"? Дадатковае пацвержанне спатрэбіцца і непасрэдна перад запісам на дыск. Could not mount partition %s. MainWindow Не ўдалося змантаваць падзел %s. The partition %s has been successfully formatted.\n MainWindow Падзел %s паспяхова фарматаваны.\n +Change parameters MainWindow Змяніць параметры The partition %s is already unmounted. MainWindow Падзел %s ужо змантаваны. Failed to delete the partition. No changes have been written to disk. MainWindow Не ўдалося выдаліць падзел. Змены не былі запісаны на дыск. Could not delete the selected partition. MainWindow Немагчыма выдаліць абраны падзел. @@ -36,38 +37,53 @@ Write changes MainWindow Запісаць змены There was an error preparing the disk for modifications. MainWindow Адбылася памылка пры падрыхтоўцы дыску да мадыфікацый. The partition %s is already mounted. MainWindow Падзел %s ужо змантаваны. Are you sure you want to format the partition? You will be asked again before changes are written to the disk. MainWindow Вы упэўнены, што жадаеце фарматаваць падзел? Дадатковае пацвержанне спатрэбіцца і непасрэдна перад запісам на дыск. +Partition name: ChangeParametersPanel Імя падзела: +Change ChangeParametersPanel Змяніць Are you sure you want to write the changes back to disk now?\n\nAll data on the disk %s will be irretrievably lost if you do so! MainWindow Сапраўды жадаеце запісаць змены на дыск?\n\nУсе данные на абраным падзеле %s будуць беззваротна згублены! Are you sure you want to delete the selected partition?\n\nAll data on the partition will be irretrievably lost if you do so! MainWindow Сапрўды жадаеце выдаліць абраны падзел?\n\nУсе данные на абраным падзеле будуць беззваротна згублены! Create… MainWindow Стварыць… Disk system \"%s\"\" not found! MainWindow Дыскавая сістэма \"%s\"\" не знойдзена! The disk has been successfully initialized.\n MainWindow Дыск быў паспяхова ініцыялізаваны.\n Could not unmount partition %s. MainWindow Не ўдалося змантаваць падзел %s. +Failed to change the parameters of the partition. No changes have been written to disk. MainWindow Не ўдалося зманіць параметры падзела. Змены не былі запісаныя на дыск. Failed to format the partition %s!\n MainWindow Не ўдалося фарматаваць падзел %s!\n Mount MainWindow Змантаваць +Partition type PartitionList Тып падзела Are you sure you want to format a raw disk? (most people initialize the disk with a partitioning system first) You will be asked again before changes are written to the disk. MainWindow Вы упэўнены, што жадаеце фарматаваць ўвесь дыск? (у большасці выпадкаў на дыску ствараюць сыстэму падзелаў) Дадатковае пацвержанне спатрэбіцца і непасрэдна перад запісам на дыск. +The panel experienced a problem! MainWindow З панэллю ёсьць пэўная праблема! +Change parameters… MainWindow Змяніць параметры… Device PartitionList Прылада Disk MainWindow Дыск Are you sure you want to initialize the selected disk? All data will be lost. You will be asked again before changes are written to the disk.\n MainWindow Вы упэўнены, што жадаеце ініцыялізаваць абраны дыск? Усе дадзеныя з яго будуць страчаны. Дадатковае пацвержанне спатрэбіцца і непасрэдна перад запісам на дыск.\n +Partition size CreateParametersPanel Памер падзела Device DiskView Прылада Active PartitionList Актыўны Volume name PartitionList Імя тому Continue MainWindow Працягнуць Cannot delete the selected partition. MainWindow Немагчыма выдаліць абраны падзел. Mount all MainWindow Зманатаваць усё +End: %s Support Канец: %s +The panel could not return successfully. MainWindow Панэль не можа вярнуцца карэктна. Cancel MainWindow Адмяніць Delete partition MainWindow Выдаліць падзел +Are you sure you want to change parameters of the selected partition?\n\nThe partition may no longer be recognized by other operating systems anymore! MainWindow Вы ўпэўнены, што жадаеце зманіць параметры абранага падзел?\n\nГэты падзел можа стаць нераспазнаваным для іншых аперацыйных сістэм! Eject MainWindow Выцягнуць Partition MainWindow Падзел +Validation of the given parameters failed. MainWindow Не удалася праверка дадзеных параметраў стварэння падзелу. +Create CreateParametersPanel Стварыць File system PartitionList Файлавая сістэма Validation of the given creation parameters failed. MainWindow Не удалася праверка дадзеных параметраў стварэння падзелу. +Partition type: ChangeParametersPanel Тып падзела: Size PartitionList Памер Wipe (not implemented) MainWindow Вынішчыць усе дадзеныя (пакуль не працуе) Validation of the given initialization parameters failed. MainWindow Не удалася праверка дадзеных параметраў ініцыялізацыі падзелу. The selected partition does not contain a partitioning system. MainWindow Абраны падзел не мае сістымы дзялення. +Offset: %s Support Зрух: %s Are you sure you want to write the changes back to disk now?\n\nAll data on the partition %s will be irretrievably lost if you do so! MainWindow Сапрўды жадаеце запісаць змены на дыск?\n\nУсе данные на абраным падзеле %s будуць беззваротна згублены! The partition %s is currently mounted. MainWindow Падзел %s зараз змантаваны. Surface test (not implemented) MainWindow Тэст паверхні (не ажыццявіма) Format MainWindow Фарматаваць +Could not change the parameters of the selected partition. MainWindow Немагчыма змяніць параметры абранага падзела. Parameters PartitionList Параметры Creation of the partition has failed. MainWindow Не удалося стварыць падзел. The currently selected partition is not empty. MainWindow Абраны зараз падзел не пусты. diff --git a/data/catalogs/apps/drivesetup/de.catkeys b/data/catalogs/apps/drivesetup/de.catkeys index 0626b1f558..3b97f07800 100644 --- a/data/catalogs/apps/drivesetup/de.catkeys +++ b/data/catalogs/apps/drivesetup/de.catkeys @@ -36,7 +36,7 @@ Are you sure you want to write the changes back to disk now?\n\nAll data on the Write changes MainWindow Änderungen schreiben There was an error preparing the disk for modifications. MainWindow Beim Vorbereiten der Änderungen trat ein interner Fehler auf. The partition %s is already mounted. MainWindow Die Partition \"%s\" ist bereits eingehangen. -Are you sure you want to format the partition? You will be asked again before changes are written to the disk. MainWindow Soll die Partition \"%s\" wirklich formatiert werden? Die Änderungen werden erst nach einer weiteren Bestätigung geschrieben. +Are you sure you want to format the partition? You will be asked again before changes are written to the disk. MainWindow Soll die Partition wirklich formatiert werden? Die Änderungen werden erst nach einer weiteren Bestätigung geschrieben. Partition name: ChangeParametersPanel Partitionsname: Change ChangeParametersPanel Ändern Are you sure you want to write the changes back to disk now?\n\nAll data on the disk %s will be irretrievably lost if you do so! MainWindow Sollen die Änderungen wirklich auf den Datenträger geschrieben werden?\n\nAlle Daten auf dem Medium \"%s\" gehen dabei unwiderruflich verloren! diff --git a/data/catalogs/apps/drivesetup/pl.catkeys b/data/catalogs/apps/drivesetup/pl.catkeys index a8c77188c7..962ee62fd1 100644 --- a/data/catalogs/apps/drivesetup/pl.catkeys +++ b/data/catalogs/apps/drivesetup/pl.catkeys @@ -1,4 +1,4 @@ -1 polish x-vnd.Haiku-DriveSetup 484941621 +1 polish x-vnd.Haiku-DriveSetup 3102001288 DriveSetup System name DriveSetup Cancel AbstractParametersPanel Anuluj Delete MainWindow Usuń @@ -68,6 +68,7 @@ Delete partition MainWindow Usuń partycję Are you sure you want to change parameters of the selected partition?\n\nThe partition may no longer be recognized by other operating systems anymore! MainWindow Czy jesteś pewna/pewny, że chcesz zmienić parametry wybranej partycji?\n\nPartycja może już nie być rozpoznawalna przez inne systemy operacyjne! Eject MainWindow Wysuń Partition MainWindow Partycja +Create CreateParametersPanel Utwórz File system PartitionList System plików Validation of the given creation parameters failed. MainWindow Sprawdzenie poprawności parametrów tworzenia partycji nie powiodło się. Partition type: ChangeParametersPanel Typ partycji: diff --git a/data/catalogs/apps/drivesetup/ru.catkeys b/data/catalogs/apps/drivesetup/ru.catkeys index db908bf518..f3ceae91a0 100644 --- a/data/catalogs/apps/drivesetup/ru.catkeys +++ b/data/catalogs/apps/drivesetup/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Haiku-DriveSetup 2015202924 +1 russian x-vnd.Haiku-DriveSetup 3775412465 DriveSetup System name Разметка диска Cancel AbstractParametersPanel Отмена Delete MainWindow Удалить @@ -45,10 +45,12 @@ Create… MainWindow Создать… Disk system \"%s\"\" not found! MainWindow Дисковая система \"%s\"\" не обнаружена! The disk has been successfully initialized.\n MainWindow Диск был успешно инициализирован.\n Could not unmount partition %s. MainWindow Невозможно отключить раздел %s. +Failed to change the parameters of the partition. No changes have been written to disk. MainWindow Не удалось изменить параметры раздела. Изменения не были записаны на диск. Failed to format the partition %s!\n MainWindow Не удалось инициализировать раздел %s!\n Mount MainWindow Подключить Partition type PartitionList Тип раздела Are you sure you want to format a raw disk? (most people initialize the disk with a partitioning system first) You will be asked again before changes are written to the disk. MainWindow Вы уверены, что хотите инициализировать весь диск? (обычно на диске создают систему разделов)\nПовторный запрос будет выдан непосредственно перед записью изменений на диск. +The panel experienced a problem! MainWindow С панелью произошла проблема! Change parameters… MainWindow Изменить параметры… Device PartitionList Устройство Disk MainWindow Диск @@ -61,8 +63,10 @@ Continue MainWindow Продолжить Cannot delete the selected partition. MainWindow Невозможно удалить выбранный раздел. Mount all MainWindow Подключить все End: %s Support Конец: %s +The panel could not return successfully. MainWindow Панели не удалось корректно вернуться. Cancel MainWindow Отмена Delete partition MainWindow Удалить раздел +Are you sure you want to change parameters of the selected partition?\n\nThe partition may no longer be recognized by other operating systems anymore! MainWindow Вы уверены, что хотите изменить параметры выбранного раздела?\n\nРаздел может больше не распознаваться другими операционными системами! Eject MainWindow Извлечь Partition MainWindow Раздел Validation of the given parameters failed. MainWindow Проверка введённых параметров не удалась. @@ -79,6 +83,7 @@ Are you sure you want to write the changes back to disk now?\n\nAll data on the The partition %s is currently mounted. MainWindow Раздел %s в данный момент подключен. Surface test (not implemented) MainWindow Тест поверхности (еще не реализовано) Format MainWindow Инициализировать +Could not change the parameters of the selected partition. MainWindow Невозможно изменить параметры выбранного раздела. Parameters PartitionList Параметры Creation of the partition has failed. MainWindow Не удалось создать раздел. The currently selected partition is not empty. MainWindow Текущий выбранный раздел не является пустым. diff --git a/data/catalogs/apps/firstbootprompt/be.catkeys b/data/catalogs/apps/firstbootprompt/be.catkeys index 63abce77e1..68702bba37 100644 --- a/data/catalogs/apps/firstbootprompt/be.catkeys +++ b/data/catalogs/apps/firstbootprompt/be.catkeys @@ -1,5 +1,6 @@ -1 belarusian x-vnd.Haiku-FirstBootPrompt 988630706 +1 belarusian x-vnd.Haiku-FirstBootPrompt 2649051796 Custom BootPromptWindow Карыстальніка +Boot to Desktop BootPromptWindow Загрузіць Працоўны Стол Thank you for trying out Haiku! We hope you'll like it!\n\nYou can select your preferred language and keyboard layout from the list on the left which will then be used instantly. You can easily change both settings from the Desktop later on on the fly.\n\nDo you wish to run the Installer or continue booting to the Desktop?\n BootPromptWindow For other languages, a note could be added: \"Note: Localization of Haiku applications and other components is an on-going effort. You will frequently encounter untranslated strings, but if you like, you can join in the work at .\" Мы дзякуем вас за спробу усталяваць Haiku. Спадзяемся, што вам спадабаецца!\n\nВы можаце абраць пажаданую мову інтэрфейса і раскладку клавіятуры ў левым спісе. Гэтыя параметры таксма могуць быць змененыя пазней.\n\nЖадаеце запусціць Усталёўшчык ці загрузіць Дэсктоп?\n Language BootPromptWindow Мова Welcome to Haiku! BootPromptWindow Вітаем! diff --git a/data/catalogs/apps/installer/hu.catkeys b/data/catalogs/apps/installer/hu.catkeys index 19ff180240..9d7d92512b 100644 --- a/data/catalogs/apps/installer/hu.catkeys +++ b/data/catalogs/apps/installer/hu.catkeys @@ -7,13 +7,13 @@ Newer versions of GRUB use an extra configuration file to add custom entries to Here you have to comment out the line \"GRUB_HIDDEN_TIMEOUT=0\" by putting a \"#\" in front of it in order to actually display the boot menu.\n\n InstallerApp Itt a \"GRUB_HIDDEN_TIMEOUT=0\" sor elé rakjon egy \"#\" jelet ha azt szeretné, hogy a boot menü ténylegesen meg is jelenjen.\n\n Installation completed. Boot sector has been written to '%s'. Press Quit to leave the Installer or choose a new target volume to perform another installation. InstallerWindow A telepítés befejeződött! A(z) „%s” lemez bootszektora elkészült. A „Kilépés” gombbal elhagyhatja a telepítőt, vagy új partíciót választhat egy új rendszer telepítéséhez. Quit InstallerApp Kilépés -Additional disk space required: 0.0 KiB InstallerWindow Még 0.0 KB hely kell. +Additional disk space required: 0.0 KiB InstallerWindow 0.0 KB hely szükséges With GRUB it's: (hdN,n)\n\n InstallerApp A GRUB esetében ez: (hdN,n)\n\n \tsudo update-grub\n\n\n InstallerApp \tsudo update-grub\n\n\n Stop InstallerWindow In alert after pressing Stop Leállítás -Install progress: InstallerWindow Telepítés állapota: +Install progress: InstallerWindow Másolás: 2.2) GRUB 1\n InstallerApp 2.1) GRUB 1\n -Starting Installation. InstallProgress A telepítés előkészítése. +Starting Installation. InstallProgress A telepítés előkészítése… This is alpha-quality software! It means there is a high risk of losing important data. Make frequent backups! You have been warned.\n\n\n InstallerApp Ez a szoftver alfa verziójú! Ebből következik, hogy adatvesztés könnyen előfordulhat. Gyakran csináljon biztonsági mentéseket! Mi szóltunk.\n\n\n Are you sure you want to abort the installation? InstallerWindow Biztos meg kívánja szakítani a telepítést? Are you sure you want to install onto the current boot disk? The Installer will have to reboot your machine if you proceed. InstallProgress Biztosan a mostani rendszerindító lemezre telepíti a rendszert? A telepítőnek újra kell indítania a számítógépét, hogy folytathassa a műveletet. @@ -28,14 +28,14 @@ Install from: InstallerWindow Honnan: %1ld of %2ld InstallerWindow number of files copied %1ld/%2ld IMPORTANT INFORMATION BEFORE INSTALLING HAIKU\n\n InstallerApp FONTOS TUDNIVALÓK A HAIKU TELEPÍTÉSE ELŐTT\n\n Continue InstallerWindow In alert after pressing Stop Folytatás -Write boot sector to '%s' InstallerWindow Bootszektor írása „%s” helyre -Collecting copy information. InstallProgress Másolás információinak összegyűjtése. +Write boot sector to '%s' InstallerWindow Bootszektor írása: „%s” +Collecting copy information. InstallProgress Másolás információinak összegyűjtése… Choose the source disk from the pop-up menu. Then click \"Begin\". InstallerWindow Válassza ki a felugró menüből a lemezt melyről telepíteni szeretne, majd kattintson a „Mehet” gombra. Quit Boot Manager and DriveSetup InstallerWindow Kilépés a Rendszerválasztóból és a Lemezkezelőből Quit InstallerWindow Kilépés Welcome to the Haiku Installer!\n\n InstallerApp Üdvözöljük a Haiku Telepítőjében!\n\n Boot sector successfully written. InstallProgress A rendszerindító szektor módosítva lett. -Performing installation. InstallProgress A telepítés folyamatban! +Performing installation. InstallProgress A telepítés folyamatban… scanning… InstallerWindow keresés… Set up boot menu InstallerWindow Rendszerválasztó beállítása 2.1) GRUB (since os-prober v1.44)\n InstallerApp 2.1) GRUB (v1.44 óta)\n @@ -43,7 +43,7 @@ The first logical partition always has the number \"4\", regardless of the numbe GRUB's naming scheme is still: (hdN,n)\n\n InstallerApp A GRUB elnevezései még mindig így néznek ki: (hdN,n)\n\n \tsudo /boot/grub/menu.lst\n\n InstallerApp \tsudo /boot/grub/menu.lst\n\n Abort InstallerWindow Megszakítás -Finishing Installation. InstallProgress Telepítés befejezése. +Finishing Installation. InstallProgress Telepítés befejezése… \tsudo /etc/default/grub\n\n InstallerApp \tsudo /etc/default/grub\n\n Restart InstallerWindow Újraindítás README InstallerApp OLVASSEL @@ -52,7 +52,7 @@ Please close the Boot Manager and DriveSetup windows before closing the Installe Scanning for disks… InstallerWindow Lemezek keresése… 2.3) GRUB 2\n InstallerApp 2.2) GRUB 2\n The disk can't be mounted. Please choose a different disk. InstallProgress A lemez nem csatolható. Válasszon egy másikat! -?? of ?? InstallerWindow Unknown progress ??/?? +?? of ?? InstallerWindow Unknown progress ?? / ?? \tmenuentry \"Haiku Alpha\" {\n InstallerApp \tmenuentry \"Haiku Alpha\" {\n Launch the DriveSetup utility to partition\navailable hard drives and other media.\nPartitions can be initialized with the\nBe File System needed for a Haiku boot\npartition. InstallerWindow Indítsa el a Lemezbeállító segédprogramot a\nlétező merevlemezek és egyéb adathordozók\npartícionálásához! A partíciókat a Haiku\noperációs rendszer rendszerbetöltőjéhez\n BFS-sel (Be FájlrendSzerrel) kell inicializálni. Show optional packages InstallerWindow Választható csomagok megjelenítése @@ -104,11 +104,11 @@ Continue InstallerApp Folytatás BootManager, the application to configure the Haiku boot menu, could not be launched. InstallerWindow A programot, ami a Haiku boot menüjét állítaná be, nem sikerült elindítani. Configure your /boot/grub/menu.lst by launching your favorite editor from a Terminal like this:\n\n InstallerApp Írja át a /boot/grub/menu.lst fájlt valamilyen szövegszerkesztővel így:\n\n Boot sector not written because of an internal error. InstallProgress A Boot szektorba egy belső hiba miatt nem lehetett írni. -Additional disk space required: %s InstallerWindow Még ennyi hely szükségeltetik: %s +Additional disk space required: %s InstallerWindow Még ennyi hely szükséges: %s NOTE: While the naming strategy for hard disks is still as described under 2.1) the naming scheme for partitions has changed.\n\n InstallerApp MEGJEGYZÉS: Ugyan a merevlemezek elnevezése itt is ugyanúgy működik mint ahogy az a 2.1)-es pontban le van írva, a partíciók elnevezése máshogy működik.\n\n Cancel InstallProgress Mégse Running Boot Manager and DriveSetup…\n\nClose both applications to continue with the installation. InstallerWindow A Rendszerválasztó és a Lemezkezelő fut…\n\nA telepítés folytatásához zárja be mindkét programot. -Try installing anyway InstallProgress Feltelepítés megpróbálása +Try installing anyway InstallProgress Telepítés megpróbálása So below the heading that must not be edited, add something similar to these lines:\n\n InstallerApp Tehát a fejléc alá, amit nem szabad átírni, írjon be néhány ehhez hasonló sort:\n\n Are you sure you want to to stop the installation? InstallerWindow Biztosan félbeszakítja a telepítést? Onto: InstallerWindow Hova: diff --git a/data/catalogs/apps/launchbox/be.catkeys b/data/catalogs/apps/launchbox/be.catkeys index f4ec61ba85..2a42b7a1b6 100644 --- a/data/catalogs/apps/launchbox/be.catkeys +++ b/data/catalogs/apps/launchbox/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-LaunchBox 3016105370 +1 belarusian x-vnd.Haiku-LaunchBox 3692177981 New LaunchBox Новы Set description… LaunchBox Прызначыць апісанне… Vertical layout LaunchBox Вертыкальная расстаноўка @@ -6,6 +6,7 @@ OK LaunchBox ОК Pad 1 LaunchBox Падложка 1 last chance LaunchBox апошняя магчымасць Quit LaunchBox Выйсці +Open containing folder LaunchBox Адкрыць папку, якая змяшчае аб'ект Clear button LaunchBox Ачысціць кнопку LaunchBox System name СтартПалічка Ignore double-click LaunchBox Ігнараваць падвойны клік diff --git a/data/catalogs/apps/login/ru.catkeys b/data/catalogs/apps/login/ru.catkeys index e66fd7c931..6ba7558dd9 100644 --- a/data/catalogs/apps/login/ru.catkeys +++ b/data/catalogs/apps/login/ru.catkeys @@ -8,7 +8,7 @@ OK Login View OK error %s\n Desktop Window A return message from fDesktopShelf->Save(). It can be \"B_OK\" ошибка %s\n Login: Login View Имя пользователя: Error Login App Ошибка -You can customize the desktop shown behind the Login application by dropping replicants onto it.\n\nWhen you are finished just quit the application (Alt-Q). Login App Вы можете изменить содержимое окна, отображаемое за приложением входа в систему, поместив на него репликанты.\nПо окончанию закройте приложение используя Alt-Q. +You can customize the desktop shown behind the Login application by dropping replicants onto it.\n\nWhen you are finished just quit the application (Alt-Q). Login App Вы можете изменить содержимое окна, отображаемое за приложением входа в систему, поместив на него репликанты.\n\nПо окончании закройте приложение используя Alt-Q. Unimplemented Login App Не реализовано Welcome to Haiku Login Window Добро пожаловать в Haiku Reboot Login View Перезагрузить diff --git a/data/catalogs/apps/mediaconverter/be.catkeys b/data/catalogs/apps/mediaconverter/be.catkeys index 70495941ad..575219da33 100644 --- a/data/catalogs/apps/mediaconverter/be.catkeys +++ b/data/catalogs/apps/mediaconverter/be.catkeys @@ -1,9 +1,11 @@ -1 belarusian x-vnd.Haiku-MediaConverter 2955071341 +1 belarusian x-vnd.Haiku-MediaConverter 2722282283 Video using parameters form settings MediaConverter Відэа карыстае параметры з наладак Video encoding: MediaConverter Кадаванне відэа: +Error read audio frame %lld MediaConverter Памылка чытання фрэйма %lld No audio Audio codecs list Няма аўдыё Error MediaConverter Памылка Error loading a file MediaConverter Немагчыма адкрыць файл +Error read video frame %lld MediaConverter Памылка чытання фрэйма %lld File Error MediaConverter-FileInfo Памылка файла Open… Menu Адкрыць… Start [ms]: MediaConverter Пачатак [мсек]: @@ -22,6 +24,8 @@ Audio: MediaConverter-FileInfo Аўдыё: OK MediaConverter-FileInfo ОК seconds MediaFileInfo секундаў Source files MediaConverter Зыходныя файлы +Error writing video frame %lld MediaConverter Памылка запісу фрэйма %lld +Error writing audio frame %lld MediaConverter Памылка запіса аўдыё фрэйма %lld Cancelling MediaConverter Адмена %d byte MediaFileInfo %d байтаў Error loading files MediaConverter Немагчыма загрузіць файлы diff --git a/data/catalogs/apps/mediaconverter/hu.catkeys b/data/catalogs/apps/mediaconverter/hu.catkeys index c9f98f41a9..a322f8ef24 100644 --- a/data/catalogs/apps/mediaconverter/hu.catkeys +++ b/data/catalogs/apps/mediaconverter/hu.catkeys @@ -27,7 +27,7 @@ Source files MediaConverter Forrásfájlok Error writing video frame %lld MediaConverter Hiba történt a %lld. képkocka írása közben Error writing audio frame %lld MediaConverter Hiba történt a %lld. hang írása közben Cancelling MediaConverter Megszakítás folyamatban -%d byte MediaFileInfo %d byte +%d byte MediaFileInfo %d byte Error loading files MediaConverter Hiba történt a fájlok betöltése során Cancel MediaConverter Mégse None available Video codecs Nincs elérhető diff --git a/data/catalogs/apps/packageinstaller/hu.catkeys b/data/catalogs/apps/packageinstaller/hu.catkeys index 34be82a1aa..6bd26f3870 100644 --- a/data/catalogs/apps/packageinstaller/hu.catkeys +++ b/data/catalogs/apps/packageinstaller/hu.catkeys @@ -37,7 +37,7 @@ The directory named '%s' already exits in the given path.\nReplace the directory The package you requested has been successfully installed on your system. PackageView A kért csomag sikeresen fel lett telepítve a rendszerre. Error! \"%s\" is not a valid path.\n Packageinstaller main Hiba! Érvénytelen útvonal: %s.\n Installation type: PackageView Telepítés típusa: -Error (%s)! Could not open \"%s\".\n Packageinstaller main Hiba (%s)! Nem nyitható meg: %s\n +Error (%s)! Could not open \"%s\".\n Packageinstaller main Hiba (%s)! Nem nyitható meg: \"%s\".\n Finishing installation PackageInstall Telepítés befejezése Installing package PackageStatus Csomag telepítése Ask again PackageView Kérdezze újból diff --git a/data/catalogs/apps/people/hu.catkeys b/data/catalogs/apps/people/hu.catkeys index 56f9d75494..18e27694e2 100644 --- a/data/catalogs/apps/people/hu.catkeys +++ b/data/catalogs/apps/people/hu.catkeys @@ -13,7 +13,7 @@ New person People Új névjegy Select all People Mind kijelölése File People Fájl Unnamed person People Névtelen személy -Could not create %s. People %s létrehozása sikertelen +Could not create %s. People %s létrehozása sikertelen. Country People Ország Close People Bezárás Group People Csoport @@ -41,7 +41,7 @@ Address People Cím URL People URL Sorry People Sajnálom Zip People Irányítószám -Contact information for a person. Long mimetype description Elérhetőség információk +Contact information for a person. Long mimetype description Elérhetőség információk. Fax People Fax Contact name People Kapcsolat neve Cut People Kivágás diff --git a/data/catalogs/apps/processcontroller/be.catkeys b/data/catalogs/apps/processcontroller/be.catkeys index 477240a7ac..6f49ce01d9 100644 --- a/data/catalogs/apps/processcontroller/be.catkeys +++ b/data/catalogs/apps/processcontroller/be.catkeys @@ -1,14 +1,14 @@ -1 belarusian x-vnd.Haiku-ProcessController 2887520383 +1 belarusian x-vnd.Haiku-ProcessController 1848752768 Memory usage ProcessController Ужыванне памяці -Do you really want to kill the team \"%s\"? ProcessController Сапраўды жадаеце знішчыць групу \"%s\"? +Kill this team! ProcessController Знішчыць паток! Idle priority ProcessController Прыярытэт спакою Restart Deskbar ProcessController Перазапусціць Deskbar Custom priority ProcessController Нестандартны прыярытэт -Debug thread ProcessController Адладжваць паток This team is already gone… ProcessController Гэтая група ўжо не існуе… Error saving file ProcessController Памылка пры захаванні файла Real-time priority ProcessController Прыярытэт рэальнага часу Your setting file could not be saved!\n(%s) ProcessController Немагчыма захаваць файл з наладкамі!\n(%s) +What do you want to do with the team \"%s\"? ProcessController Што вы жадаеце зрабіць з патокам \"%s\"? This thread is already gone… ProcessController Гэты паток ўжо не існуе… Cancel ProcessController Адмена Display priority ProcessController Прыярытэт адлюстравання @@ -38,11 +38,11 @@ Threads and CPU usage ProcessController Патокі і ўжыванне ЦП Urgent display priority ProcessController Прыярытэт неадкладнага адлюстравання OK ProcessController ОК Damned! ProcessController Чорт! +Debug this team! ProcessController Адладжваць паток! Usage: %s [-deskbar]\n ProcessController Ужыванне: %s [-deskbar]\n ProcessController System name Працэсы і патокі Real-time display priority ProcessController Прыярытэт адлюстравання ў рэальным часе Please confirm ProcessController Калі ласка падцвердзіце -Yes, kill this team! ProcessController Так, знішчыць гэтую групу! System resources & caches… ProcessController Сістэмныя рэсурсы & кэш… That's no Fun! ProcessController Гэта непрыкольна! You can run ProcessController in a window or install it in the Deskbar. ProcessController Вы можаце запускаць ProcessController у вакне або ўсталяваць яго ў Deskbar. diff --git a/data/catalogs/apps/processcontroller/de.catkeys b/data/catalogs/apps/processcontroller/de.catkeys index cc625c326b..da05876a03 100644 --- a/data/catalogs/apps/processcontroller/de.catkeys +++ b/data/catalogs/apps/processcontroller/de.catkeys @@ -1,14 +1,14 @@ -1 german x-vnd.Haiku-ProcessController 2887520383 +1 german x-vnd.Haiku-ProcessController 1848752768 Memory usage ProcessController Speicherverbrauch -Do you really want to kill the team \"%s\"? ProcessController Soll das Team \"%s\" wirklich beendet werden? +Kill this team! ProcessController Dieses Team beenden! Idle priority ProcessController Leerlauf-Priorität Restart Deskbar ProcessController Deskbar neu starten Custom priority ProcessController Anwendungsspezifische Priorität -Debug thread ProcessController Debug Thread This team is already gone… ProcessController Dieses Team existiert nicht mehr… Error saving file ProcessController Fehler beim Speichern der Datei Real-time priority ProcessController Echtzeit-Priorität Your setting file could not be saved!\n(%s) ProcessController Die Einstellungsdatei konnte nicht gespeichert werden.\n(%s) +What do you want to do with the team \"%s\"? ProcessController Was soll mit dem Team \"%s\" geschehen? This thread is already gone… ProcessController Dieser Thread existiert nicht mehr… Cancel ProcessController Abbrechen Display priority ProcessController Anzeigen-Priorität @@ -38,11 +38,11 @@ Threads and CPU usage ProcessController Threads und CPU-Last Urgent display priority ProcessController Hohe Anzeigen-Priorität OK ProcessController OK Damned! ProcessController Herrje! +Debug this team! ProcessController Dieses Team debuggen! Usage: %s [-deskbar]\n ProcessController Gebrauch: %s [-deskbar]\n ProcessController System name Systemmanager Real-time display priority ProcessController Echtzeit-Anzeigen-Priorität Please confirm ProcessController Bitte bestätigen -Yes, kill this team! ProcessController Ja, dieses Team beenden! System resources & caches… ProcessController Systemressourcen & Cache… That's no Fun! ProcessController Nicht lustig! You can run ProcessController in a window or install it in the Deskbar. ProcessController Der Systemmanager kann im Fenster ausgeführt oder in der Deskbar installiert werden. diff --git a/data/catalogs/apps/processcontroller/el.catkeys b/data/catalogs/apps/processcontroller/el.catkeys index 00df81a8b7..8e823da153 100644 --- a/data/catalogs/apps/processcontroller/el.catkeys +++ b/data/catalogs/apps/processcontroller/el.catkeys @@ -1,10 +1,8 @@ -1 greek, modern (1453-) x-vnd.Haiku-ProcessController 2887520383 +1 greek, modern (1453-) x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Χρήση μνήμης -Do you really want to kill the team \"%s\"? ProcessController Θέλετε σίγουρα να τερματίσετε την ομάδα \"%s\"; Idle priority ProcessController Ανενεργή προτεραιότητα Restart Deskbar ProcessController Επανεκκίνηση Deskbar Custom priority ProcessController Προσαρμοσμένη προτεραιότητα -Debug thread ProcessController Αποσφαλμάτωση νήματος This team is already gone… ProcessController Αυτή η όμαδα έχει ήδη εξαφανιστεί Error saving file ProcessController Σφάλμα κατα την αποθήκευση του αρχείου Real-time priority ProcessController Προτεραιότητα πραγματικού χρόνου @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Χρήση: %s [-deskbar]\n ProcessController System name ProcessController Real-time display priority ProcessController Προτεραιότητα εμφάνισης πραγματικού χρόνου Please confirm ProcessController Παρακαλώ επιβεβαιώστε -Yes, kill this team! ProcessController Ναι, τερματισμός της ομάδας! System resources & caches… ProcessController Πόροι & λανθάνουσα μνήμη συστήματος... That's no Fun! ProcessController Αυτό δεν έχει πλάκα! You can run ProcessController in a window or install it in the Deskbar. ProcessController Μπορείτε να εκτελέσετε το ProcessController σε ένα παράθυρο ή να το εγκαταστήσετε στη Deskbar. diff --git a/data/catalogs/apps/processcontroller/fi.catkeys b/data/catalogs/apps/processcontroller/fi.catkeys index 6457d173c0..055a814d90 100644 --- a/data/catalogs/apps/processcontroller/fi.catkeys +++ b/data/catalogs/apps/processcontroller/fi.catkeys @@ -1,10 +1,8 @@ -1 finnish x-vnd.Haiku-ProcessController 2887520383 +1 finnish x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Muistikäyttö -Do you really want to kill the team \"%s\"? ProcessController Haluatko todella lopettaa ryhmän ”%s”? Idle priority ProcessController Joutokäyntiprioriteetti Restart Deskbar ProcessController Käynnistä Työpöytäpalkki uudelleen Custom priority ProcessController Räätälöity prioriteetti -Debug thread ProcessController Vikajäljitä säiettä This team is already gone… ProcessController Tämä ryhmä on jo poistunut... Error saving file ProcessController Virhe tallennettaessa tiedostoa Real-time priority ProcessController Ajantasaprioriteetti @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Käyttö: %s [-deskbar]\n ProcessController System name Prosessiohjain Real-time display priority ProcessController Ajantasanäyttöprioriteetti Please confirm ProcessController Vahvista -Yes, kill this team! ProcessController Kyllä, lopeta tämä ryhmä! System resources & caches… ProcessController Järjestelmäresurssit ja välimuistit… That's no Fun! ProcessController Se ei ole hauskaa! You can run ProcessController in a window or install it in the Deskbar. ProcessController Voit suorittaa Prosessiohjaimen ikkunassa tai asentaa sen Työpöytäpalkkiin. diff --git a/data/catalogs/apps/processcontroller/fr.catkeys b/data/catalogs/apps/processcontroller/fr.catkeys index 903b1539ee..72a7e60411 100644 --- a/data/catalogs/apps/processcontroller/fr.catkeys +++ b/data/catalogs/apps/processcontroller/fr.catkeys @@ -1,14 +1,14 @@ -1 french x-vnd.Haiku-ProcessController 2887520383 +1 french x-vnd.Haiku-ProcessController 1848752768 Memory usage ProcessController Consommation mémoire -Do you really want to kill the team \"%s\"? ProcessController Voulez-vous vraiment tuer le processus « %s » ? +Kill this team! ProcessController Tuer ce processus ! Idle priority ProcessController Priorité inactive Restart Deskbar ProcessController Redémarrer la Deskbar Custom priority ProcessController Priorité personnalisée -Debug thread ProcessController Déboguer la tâche This team is already gone… ProcessController Ce processus n'existe déjà plus… Error saving file ProcessController Erreur à l'enregistrement du fichier Real-time priority ProcessController Priorité temps-réel Your setting file could not be saved!\n(%s) ProcessController Impossible d'enregistrer votre fichier de réglages !\n(%s) +What do you want to do with the team \"%s\"? ProcessController Que voulez vous faire du processus « %s » ? This thread is already gone… ProcessController Cette tâche n'existe déjà plus… Cancel ProcessController Annuler Display priority ProcessController Priorité affichage @@ -38,11 +38,11 @@ Threads and CPU usage ProcessController Tâches et activité CPU Urgent display priority ProcessController Priorité affichage urgent OK ProcessController OK Damned! ProcessController Damnation ! +Debug this team! ProcessController Déboguer ce processus ! Usage: %s [-deskbar]\n ProcessController Utilisation : %s [-deskbar]\n ProcessController System name ProcessControlleur Real-time display priority ProcessController Priorité affichage temps-réel Please confirm ProcessController Veuillez confirmer -Yes, kill this team! ProcessController Oui, tuer ce processus ! System resources & caches… ProcessController Resources du système & caches… That's no Fun! ProcessController C'est pas fun ! You can run ProcessController in a window or install it in the Deskbar. ProcessController Vous pouvez exécuter ProcessControlleur dans une fenêtre ou l'installer dans la Deskbar. diff --git a/data/catalogs/apps/processcontroller/hi.catkeys b/data/catalogs/apps/processcontroller/hi.catkeys index 0fbc7e71f3..2fffa010d9 100644 --- a/data/catalogs/apps/processcontroller/hi.catkeys +++ b/data/catalogs/apps/processcontroller/hi.catkeys @@ -1,10 +1,8 @@ -1 hindi x-vnd.Haiku-ProcessController 2887520383 +1 hindi x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController स्मृति के उपयोग -Do you really want to kill the team \"%s\"? ProcessController क्या आप वास्तव में टीम को मारना चाहते हैं \"%s\"? Idle priority ProcessController आइडल प्राथमिकता Restart Deskbar ProcessController डेस्कबार पुनः आरंभ करें Custom priority ProcessController प्राथमिकता कस्टम है -Debug thread ProcessController डिबग थ्रेड This team is already gone… ProcessController यह टीम पहले से ही जा चुकी है... Error saving file ProcessController त्रुटि फ़ाइल सहेजने मैं Real-time priority ProcessController रियल-टाइम प्राथमिकता @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController प्रयोग: %s [-डेस् ProcessController System name ProcessController Real-time display priority ProcessController प्राथमिकता रियल-टाइम डिस्प्ले है Please confirm ProcessController कृपया पक्का करें -Yes, kill this team! ProcessController हाँ, यह टीम को मार डालो! System resources & caches… ProcessController सिस्टम रिसोर्से & कैशेस... That's no Fun! ProcessController वह कुछ भी मज़ा नहीं है! You can run ProcessController in a window or install it in the Deskbar. ProcessController आप एक खिड़की में प्रक्रिया नियंत्रक रन कर सकते या उसको डेस्कबार में स्थापित कर सकते हैं. diff --git a/data/catalogs/apps/processcontroller/hu.catkeys b/data/catalogs/apps/processcontroller/hu.catkeys index 5718e09842..5e37e1ee6c 100644 --- a/data/catalogs/apps/processcontroller/hu.catkeys +++ b/data/catalogs/apps/processcontroller/hu.catkeys @@ -1,14 +1,14 @@ -1 hungarian x-vnd.Haiku-ProcessController 2887520383 +1 hungarian x-vnd.Haiku-ProcessController 1848752768 Memory usage ProcessController Memóriahasználat -Do you really want to kill the team \"%s\"? ProcessController Biztosan le kívánja állítani: %s? +Kill this team! ProcessController Szál leállítása! Idle priority ProcessController Üresjárat prioritás Restart Deskbar ProcessController Asztalsáv újraindítása Custom priority ProcessController Egyéni prioritás -Debug thread ProcessController Szál hibakeresése This team is already gone… ProcessController Ez a csapat már eltűnt… Error saving file ProcessController Hiba történt a fájl mentése során Real-time priority ProcessController Valós idejű prioritás Your setting file could not be saved!\n(%s) ProcessController A beállításfájlt nem sikerült elmenteni!\n(%s) +What do you want to do with the team \"%s\"? ProcessController Mit kíván tenni a szállal: %s? This thread is already gone… ProcessController Ez a szál már eltűnt… Cancel ProcessController Mégse Display priority ProcessController Kijelzési prioritás @@ -38,11 +38,11 @@ Threads and CPU usage ProcessController Szálak és processzorhasználat Urgent display priority ProcessController Magas kijelzési prioritás OK ProcessController Rendben Damned! ProcessController Fenébe! +Debug this team! ProcessController Szál hibakeresése! Usage: %s [-deskbar]\n ProcessController Használat: %s [-deskbar]\n ProcessController System name Folyamatkezelő Real-time display priority ProcessController Valós idejű kijelzési prioritás Please confirm ProcessController Jóváhagyás -Yes, kill this team! ProcessController Igen, állítsa le a csapatot! System resources & caches… ProcessController Rendszer erőforrásai és gyorsítótárai… That's no Fun! ProcessController Ez nem vicces! You can run ProcessController in a window or install it in the Deskbar. ProcessController Futtathatja a Folyamatkezelőt egy ablakban, vagy feltelepítheti azt az Asztalsávra. diff --git a/data/catalogs/apps/processcontroller/ja.catkeys b/data/catalogs/apps/processcontroller/ja.catkeys index c78c2a88a3..dd0f30974d 100644 --- a/data/catalogs/apps/processcontroller/ja.catkeys +++ b/data/catalogs/apps/processcontroller/ja.catkeys @@ -1,14 +1,14 @@ -1 japanese x-vnd.Haiku-ProcessController 2887520383 +1 japanese x-vnd.Haiku-ProcessController 1848752768 Memory usage ProcessController メモリ使用量 -Do you really want to kill the team \"%s\"? ProcessController 本当に team \"%s\" を強制終了してよいですか? +Kill this team! ProcessController スレッドを強制終了 Idle priority ProcessController アイドル優先度 Restart Deskbar ProcessController Deskbar を再起動 Custom priority ProcessController カスタム優先度 -Debug thread ProcessController スレッドをデバッグ This team is already gone… ProcessController Team はすでに終了しています… Error saving file ProcessController ファイル保存中にエラーが発生しました Real-time priority ProcessController リアルタイム優先度 Your setting file could not be saved!\n(%s) ProcessController 設定ファイルは保存できませんでした。\n(%s) +What do you want to do with the team \"%s\"? ProcessController スレッド \"%s\" に対してなにをしたいですか? This thread is already gone… ProcessController スレッドはすでに終了しています… Cancel ProcessController 取り消し Display priority ProcessController 表示優先度 @@ -38,11 +38,11 @@ Threads and CPU usage ProcessController スレッドと CPU の使用量 Urgent display priority ProcessController 緊急表示優先度 OK ProcessController OK Damned! ProcessController とんでもない! +Debug this team! ProcessController スレッドをデバッグ Usage: %s [-deskbar]\n ProcessController Usage: %s [-deskbar]\n ProcessController System name プロセスコントローラー Real-time display priority ProcessController リアルタイム表示優先度 Please confirm ProcessController 確認してください。 -Yes, kill this team! ProcessController はい、team を強制終了します ! System resources & caches… ProcessController システムリソースとキャッシュ… That's no Fun! ProcessController そんなのおもしろくない! You can run ProcessController in a window or install it in the Deskbar. ProcessController プロセスコントローラーをウィンドウモードで起動するか、または Deskbar にインストールできます。 diff --git a/data/catalogs/apps/processcontroller/lt.catkeys b/data/catalogs/apps/processcontroller/lt.catkeys index 8b10f709ff..114860e1dc 100644 --- a/data/catalogs/apps/processcontroller/lt.catkeys +++ b/data/catalogs/apps/processcontroller/lt.catkeys @@ -1,10 +1,8 @@ -1 lithuanian x-vnd.Haiku-ProcessController 2887520383 +1 lithuanian x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Atminties naudojimas -Do you really want to kill the team \"%s\"? ProcessController Ar tikrai norite nutraukti užduoties „%s“ darbą? Idle priority ProcessController Nulinis prioritetas Restart Deskbar ProcessController Perleisti Užduočių juostą Custom priority ProcessController Parinktinis prioritetas -Debug thread ProcessController Derinti giją This team is already gone… ProcessController Šios užduoties jau nebėra… Error saving file ProcessController Klaida įrašant failą Real-time priority ProcessController Tikralaikis prioritetas @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Naudojimas: %s [-deskbar]\n ProcessController System name Procesų valdiklis Real-time display priority ProcessController Tikralaikio rodymo prioritetas Please confirm ProcessController Prašome patvirtinti -Yes, kill this team! ProcessController Taip, nutraukti šios užduoties darbą! System resources & caches… ProcessController Sistemos ištekliai ir podėliai… That's no Fun! ProcessController Visai nejuokinga! You can run ProcessController in a window or install it in the Deskbar. ProcessController Šią programą galite paleisti atskirame lange arba patalpinti pranešimų srityje. diff --git a/data/catalogs/apps/processcontroller/nl.catkeys b/data/catalogs/apps/processcontroller/nl.catkeys index bcf693352a..3da84655cb 100644 --- a/data/catalogs/apps/processcontroller/nl.catkeys +++ b/data/catalogs/apps/processcontroller/nl.catkeys @@ -1,10 +1,8 @@ -1 dutch; flemish x-vnd.Haiku-ProcessController 2887520383 +1 dutch; flemish x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Geheugengebruik -Do you really want to kill the team \"%s\"? ProcessController Wilt u echt team \"%s\" afbreken? Idle priority ProcessController Inactieve prioriteit Restart Deskbar ProcessController Deskbar herstarten Custom priority ProcessController Aangepaste prioriteit -Debug thread ProcessController Thread debuggen This team is already gone… ProcessController Dit team is al verdwenen... Error saving file ProcessController Fout bij bestandsopslag Real-time priority ProcessController Real-time prioriteit @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Gebruik: %s [-deskbar]\n ProcessController System name ProcessController Real-time display priority ProcessController Real-time weergave prioriteit Please confirm ProcessController Gelieve te bevestigen -Yes, kill this team! ProcessController Ja, breek dit team af! System resources & caches… ProcessController Systeembronnen en -caches... That's no Fun! ProcessController Da's niet Leuk! You can run ProcessController in a window or install it in the Deskbar. ProcessController U kunt ProcessController in een venster actief hebben, of in Deskbar installeren. diff --git a/data/catalogs/apps/processcontroller/pl.catkeys b/data/catalogs/apps/processcontroller/pl.catkeys index dc475e9028..2155f8c652 100644 --- a/data/catalogs/apps/processcontroller/pl.catkeys +++ b/data/catalogs/apps/processcontroller/pl.catkeys @@ -1,10 +1,8 @@ -1 polish x-vnd.Haiku-ProcessController 2887520383 +1 polish x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Użycie pamięci -Do you really want to kill the team \"%s\"? ProcessController Czy na pewno chcesz zakończyć zespół \"%s\"? Idle priority ProcessController Priorytet bezczynności Restart Deskbar ProcessController Zrestartuj Deskbar Custom priority ProcessController Własny priorytet -Debug thread ProcessController Debuguj wątek This team is already gone… ProcessController Ten zespół nie jest już obecny… Error saving file ProcessController Błąd przy zapisywaniu pliku Real-time priority ProcessController Priorytet czasu rzeczywistego @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Użycie: %s [-deskbar]\n ProcessController System name ProcessController Real-time display priority ProcessController Czasu rzeczywistego priorytet wyświetlania Please confirm ProcessController Proszę potwierdź -Yes, kill this team! ProcessController Tak, zakończ ten zespół! System resources & caches… ProcessController Zasoby i bufory systemu… That's no Fun! ProcessController To nie zabawa! You can run ProcessController in a window or install it in the Deskbar. ProcessController Możesz uruchomić ProcessController w oknie lub zainstalować go w Deskbarze. diff --git a/data/catalogs/apps/processcontroller/pt_BR.catkeys b/data/catalogs/apps/processcontroller/pt_BR.catkeys index ee3ee27061..b6bc16ecdd 100644 --- a/data/catalogs/apps/processcontroller/pt_BR.catkeys +++ b/data/catalogs/apps/processcontroller/pt_BR.catkeys @@ -1,14 +1,14 @@ -1 portuguese (brazil) x-vnd.Haiku-ProcessController 2887520383 +1 portuguese (brazil) x-vnd.Haiku-ProcessController 1848752768 Memory usage ProcessController Uso de memória -Do you really want to kill the team \"%s\"? ProcessController Deseja realmente matar a equipe \"%s\"? +Kill this team! ProcessController Matar esta equipe! Idle priority ProcessController Prioridade ociosa Restart Deskbar ProcessController Reiniciar o Deskbar Custom priority ProcessController Prioridade personalizada -Debug thread ProcessController Processo de depuração This team is already gone… ProcessController Esta equipe já se foi… Error saving file ProcessController Erro ao gravar o arquivo Real-time priority ProcessController Prioridade em tempo real Your setting file could not be saved!\n(%s) ProcessController Arquivo de definições não pôde ser salvo!\n(%s) +What do you want to do with the team \"%s\"? ProcessController O que deseja fazer com a equipe \"%s\"? This thread is already gone… ProcessController Este processo já se foi… Cancel ProcessController Cancelar Display priority ProcessController Exibir prioridade @@ -38,11 +38,11 @@ Threads and CPU usage ProcessController Processos e utilização de CPU Urgent display priority ProcessController Exibir prioridade urgente OK ProcessController OK Damned! ProcessController Maldição! +Debug this team! ProcessController Depurar esta equipe! Usage: %s [-deskbar]\n ProcessController Utilização: %s [-deskbar]\n ProcessController System name Controlador de Processo Real-time display priority ProcessController Exibir prioridade de tempo real Please confirm ProcessController Favor confirmar -Yes, kill this team! ProcessController Sim, mate esta equipe! System resources & caches… ProcessController Recursos & caches de sistema… That's no Fun! ProcessController Isso não é Engraçado! You can run ProcessController in a window or install it in the Deskbar. ProcessController É possível executar o Controlador de Processo em uma janela ou instalá-lo no Deskbar. diff --git a/data/catalogs/apps/processcontroller/ro.catkeys b/data/catalogs/apps/processcontroller/ro.catkeys index 77a446f335..690ecc7c43 100644 --- a/data/catalogs/apps/processcontroller/ro.catkeys +++ b/data/catalogs/apps/processcontroller/ro.catkeys @@ -1,10 +1,8 @@ -1 romanian x-vnd.Haiku-ProcessController 2887520383 +1 romanian x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Utilizarea memoriei -Do you really want to kill the team \"%s\"? ProcessController Doriți să terminați forțat echipa „%s”? Idle priority ProcessController Prioritate în așteptare Restart Deskbar ProcessController Repornește bara de desktop Custom priority ProcessController Prioritate personalizată -Debug thread ProcessController Depanează firul de execuție This team is already gone… ProcessController Această echipă este plecată deja... Error saving file ProcessController Eroare la salvarea fișierului Real-time priority ProcessController Prioritate în timp real @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Utilizare: %s [-deskbar]\n ProcessController System name ControlProcese Real-time display priority ProcessController Prioritate afișaj în timp real Please confirm ProcessController Confirmați -Yes, kill this team! ProcessController Da, termină forțat această echipă! System resources & caches… ProcessController Resurse de sistem & cache-uri That's no Fun! ProcessController Nu e amuzant! You can run ProcessController in a window or install it in the Deskbar. ProcessController Puteți să rulați ControlerProces într-o fereastră sau să îl instalați pe bara de desktop. diff --git a/data/catalogs/apps/processcontroller/ru.catkeys b/data/catalogs/apps/processcontroller/ru.catkeys index 5c5f2ae9c7..7076851cfd 100644 --- a/data/catalogs/apps/processcontroller/ru.catkeys +++ b/data/catalogs/apps/processcontroller/ru.catkeys @@ -1,14 +1,14 @@ -1 russian x-vnd.Haiku-ProcessController 2887520383 +1 russian x-vnd.Haiku-ProcessController 1848752768 Memory usage ProcessController Использование памяти -Do you really want to kill the team \"%s\"? ProcessController Вы действительно хотите убить \"%s\"? +Kill this team! ProcessController Убить этот поток! Idle priority ProcessController Приоритет бездействия Restart Deskbar ProcessController Перезапустить Deskbar Custom priority ProcessController Заданный приоритет -Debug thread ProcessController Отладить поток This team is already gone… ProcessController Этого приложения уже не существует… Error saving file ProcessController Ошибка при сохранении файла Real-time priority ProcessController Приоритет реального времени Your setting file could not be saved!\n(%s) ProcessController Невозможно сохранить настройки!\n(%s) +What do you want to do with the team \"%s\"? ProcessController Что вы хотите сделать с потоком \"%s\"? This thread is already gone… ProcessController Этого потока уже не существует… Cancel ProcessController Отмена Display priority ProcessController Приоритет отображения @@ -38,11 +38,11 @@ Threads and CPU usage ProcessController Потоки и загрузка ЦПУ Urgent display priority ProcessController Срочный приоритет отображения OK ProcessController ОК Damned! ProcessController Проклятье! +Debug this team! ProcessController Отладить этот поток! Usage: %s [-deskbar]\n ProcessController Использование: %s [-deskbar]\n ProcessController System name Контроллер процессов Real-time display priority ProcessController Приоритет отображения реального времени Please confirm ProcessController Пожалуйста, подтвердите -Yes, kill this team! ProcessController Да, убить это приложение! System resources & caches… ProcessController Системные ресурсы и кеш That's no Fun! ProcessController Это не смешно! You can run ProcessController in a window or install it in the Deskbar. ProcessController Вы можете запустить контроллер процессов в окне или установить его в Deskbar. diff --git a/data/catalogs/apps/processcontroller/sk.catkeys b/data/catalogs/apps/processcontroller/sk.catkeys index fb42169a03..ec38b90d67 100644 --- a/data/catalogs/apps/processcontroller/sk.catkeys +++ b/data/catalogs/apps/processcontroller/sk.catkeys @@ -1,10 +1,8 @@ -1 slovak x-vnd.Haiku-ProcessController 2887520383 +1 slovak x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Využitie pamäte -Do you really want to kill the team \"%s\"? ProcessController Skutočne chcete ukončiť tím „%s“? Idle priority ProcessController Priorita nečinný Restart Deskbar ProcessController Reštartovať Panel Custom priority ProcessController Vlastná priorita -Debug thread ProcessController Ladiť vlákno This team is already gone… ProcessController Tento tím už je preč… Error saving file ProcessController Chyba pri ukladaní súboru Real-time priority ProcessController Priorita v reálnom čase @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Použitie: %s [-deskbar]\n ProcessController System name Správca procesov Real-time display priority ProcessController Priorita zobrazenie v reálnom čase Please confirm ProcessController Prosím, potvrďte -Yes, kill this team! ProcessController Áno, ukončiť tento tím! System resources & caches… ProcessController Zdroje a vyrovnávacia pamäť systému… That's no Fun! ProcessController To nie je sranda! You can run ProcessController in a window or install it in the Deskbar. ProcessController Správcu procesov môžete spúšťať v okne alebo ho nainštalovať do Panelu. diff --git a/data/catalogs/apps/processcontroller/sv.catkeys b/data/catalogs/apps/processcontroller/sv.catkeys index 8fb08a97e5..e933d80f5e 100644 --- a/data/catalogs/apps/processcontroller/sv.catkeys +++ b/data/catalogs/apps/processcontroller/sv.catkeys @@ -1,10 +1,8 @@ -1 swedish x-vnd.Haiku-ProcessController 2887520383 +1 swedish x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Minnesanvändning -Do you really want to kill the team \"%s\"? ProcessController Vill du verkligen avsluta processen "%s"? Idle priority ProcessController Overksam prioritet Restart Deskbar ProcessController Starta om Deskbar Custom priority ProcessController Annan prioritet -Debug thread ProcessController Felsök tråd This team is already gone… ProcessController Processen är redan avslutad... Error saving file ProcessController Fel vid sparning av fil Real-time priority ProcessController Realtidsprioritet @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Hantering: %s [-deskbar]\n ProcessController System name ProcessKontroll Real-time display priority ProcessController Realtidsvisningprioritet Please confirm ProcessController Vänligen bekräfta -Yes, kill this team! ProcessController Ja, avsluta den här processen! System resources & caches… ProcessController Systemresurser & filsystemscache… That's no Fun! ProcessController Det var inte roligt! You can run ProcessController in a window or install it in the Deskbar. ProcessController Du kan köra ProcessKontroll i ett fönster eller installera den i Deskbar. diff --git a/data/catalogs/apps/processcontroller/uk.catkeys b/data/catalogs/apps/processcontroller/uk.catkeys index 07532954ae..ec5ee6b683 100644 --- a/data/catalogs/apps/processcontroller/uk.catkeys +++ b/data/catalogs/apps/processcontroller/uk.catkeys @@ -1,10 +1,8 @@ -1 ukrainian x-vnd.Haiku-ProcessController 2887520383 +1 ukrainian x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController Використання пам'яті -Do you really want to kill the team \"%s\"? ProcessController Ви дійсно бажаєте вбити потік \"%s\"? Idle priority ProcessController Idle priority Restart Deskbar ProcessController Перезапустити Deskbar Custom priority ProcessController Заданий приорітет -Debug thread ProcessController Нитка відладки This team is already gone… ProcessController Потік повністю запущений… Error saving file ProcessController Помилка при збереженні файлу Real-time priority ProcessController Приорітет реального часу @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController Використання: %s [-deskbar ProcessController System name ProcessController Real-time display priority ProcessController Приорітет реального часу Please confirm ProcessController Повторіть -Yes, kill this team! ProcessController Так , вбити цей потік! System resources & caches… ProcessController Системні ресурси і кеші… That's no Fun! ProcessController Це не жарт! You can run ProcessController in a window or install it in the Deskbar. ProcessController Ви можете запустити ProcessController у вікні або встановити в Deskbar. diff --git a/data/catalogs/apps/processcontroller/zh_Hans.catkeys b/data/catalogs/apps/processcontroller/zh_Hans.catkeys index d873c52f3d..b85c1ca42d 100644 --- a/data/catalogs/apps/processcontroller/zh_Hans.catkeys +++ b/data/catalogs/apps/processcontroller/zh_Hans.catkeys @@ -1,10 +1,8 @@ -1 english x-vnd.Haiku-ProcessController 2887520383 +1 english x-vnd.Haiku-ProcessController 2886374724 Memory usage ProcessController 内存使用 -Do you really want to kill the team \"%s\"? ProcessController 您确定要杀死该组 \"%s\"? Idle priority ProcessController 空闲优先级 Restart Deskbar ProcessController 重启桌面栏 Custom priority ProcessController 自定义优先级 -Debug thread ProcessController 调试线程 This team is already gone… ProcessController 该组已经结束... Error saving file ProcessController 保存文件错误 Real-time priority ProcessController 实时优先级 @@ -42,7 +40,6 @@ Usage: %s [-deskbar]\n ProcessController 用法: %s [-deskbar]\n ProcessController System name 进程控制器 Real-time display priority ProcessController 实时显示优先级 Please confirm ProcessController 请确认 -Yes, kill this team! ProcessController 是的,杀死该组! System resources & caches… ProcessController 系统资源与缓存... That's no Fun! ProcessController 不好玩的! You can run ProcessController in a window or install it in the Deskbar. ProcessController 您可以在窗口中运行进程控制器或者将其安装到桌面栏。 diff --git a/data/catalogs/apps/terminal/be.catkeys b/data/catalogs/apps/terminal/be.catkeys index 56c3c41e0a..4efc779335 100644 --- a/data/catalogs/apps/terminal/be.catkeys +++ b/data/catalogs/apps/terminal/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-Terminal 328707356 +1 belarusian x-vnd.Haiku-Terminal 2967760334 Not found. Terminal TermWindow Не знойдзена. Switch Terminals Terminal TermWindow Пераключыць Тэрміналы Change directory Terminal TermView Змяніць дырэкторыю @@ -79,6 +79,7 @@ Clear all Terminal TermWindow Ачысціць усё Text encoding Terminal TermWindow Кадоўка тэксту size Terminal TermView памер Close window Terminal TermWindow Закрыць вакно +\t%d\t-\tThe current working directory of the active process in the\n\t\t\tcurrent tab. Optionally the maximum number of path components\n\t\t\tcan be specified. E.g. '%2d' for at most two components.\n\t%T\t-\tThe Terminal application name for the current locale.\n\t%e\t-\tThe encoding of the current tab. Not shown for UTF-8.\n\t%i\t-\tThe index of the window.\n\t%p\t-\tThe name of the active process in the current tab.\n\t%t\t-\tThe title of the current tab.\n\t%%\t-\tThe character '%'. Terminal ToolTips \t%d\t-\tРабочы каталог актыўнага працэсу\n\t\t\tў цякучай укладцы.Дадаткова можна ўказаць макісмальную колькасць кампанентаў пуці.\n\t\t\t Напрыклад, '%2d' - не больша за два кампаненты.\n\t%T\t-\tІмя праграмы Тэрмінала ў актуальнай лакалі.\n\t%e\t-\tКадоўка актыўнай укладкі. Калі UTF-8 то не паказваецца.\n\t%i\t-\tІндэкс вакна.\n\t%p\t-\tІмя актыўнага працэсу ў цякучай укладцы.\n\t%t\t-\tІмя цякучай укладкі.\n\t%%\t-\tСімвал '%'. Save as default Terminal TermWindow Захаваць як прадвызначаныя Set tab title Terminal TermWindow Прызначыць імя ўкладкі Settings… Terminal TermWindow Наладкі… diff --git a/data/catalogs/apps/terminal/ru.catkeys b/data/catalogs/apps/terminal/ru.catkeys index b6d2f1fd58..da7c9a9bbe 100644 --- a/data/catalogs/apps/terminal/ru.catkeys +++ b/data/catalogs/apps/terminal/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Haiku-Terminal 328707356 +1 russian x-vnd.Haiku-Terminal 2967760334 Not found. Terminal TermWindow Текст не найден Switch Terminals Terminal TermWindow Переключить терминалы Change directory Terminal TermView Сменить каталог @@ -79,6 +79,7 @@ Clear all Terminal TermWindow Очистить всё Text encoding Terminal TermWindow Кодировка size Terminal TermView размер Close window Terminal TermWindow Закрыть окно +\t%d\t-\tThe current working directory of the active process in the\n\t\t\tcurrent tab. Optionally the maximum number of path components\n\t\t\tcan be specified. E.g. '%2d' for at most two components.\n\t%T\t-\tThe Terminal application name for the current locale.\n\t%e\t-\tThe encoding of the current tab. Not shown for UTF-8.\n\t%i\t-\tThe index of the window.\n\t%p\t-\tThe name of the active process in the current tab.\n\t%t\t-\tThe title of the current tab.\n\t%%\t-\tThe character '%'. Terminal ToolTips \t%d\t-\tТекущая директория активного процесса текущей вкладки.\n\t\t\tОпционально можно указать максимальное число отображаемых компонентов пути.\n\t\t\tНапример '%2d' отобразит последние 2 компонента.\n\t%T\t-\tИмя приложения Терминал для текущей локали.\n\t%e\t-\tКодировка текущей вкладки. Для UTF-8 не отображается.\n\t%i\t-\tНомер окна.\n\t%p\t-\tНазвание активного процесса в текущей вкладке.\n\t%t\t-\tЗаголовок текущей вкладки.\n\t%%\t-\tСимвол процента - '%'. Save as default Terminal TermWindow Сохранить Set tab title Terminal TermWindow Переименовть вкладку Settings… Terminal TermWindow Настройки… diff --git a/data/catalogs/apps/webpositive/be.catkeys b/data/catalogs/apps/webpositive/be.catkeys index b5a0184ba6..4e943eb481 100644 --- a/data/catalogs/apps/webpositive/be.catkeys +++ b/data/catalogs/apps/webpositive/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-WebPositive 233049275 +1 belarusian x-vnd.Haiku-WebPositive 1786411139 Show home button Settings Window Паказваць кнопку "Дадому" Username: Authentication Panel Карыстальнік: Copy URL to clipboard Download Window Скапіяваць спасылку @@ -16,6 +16,8 @@ Start page: Settings Window Пачатковая старонка: History WebPositive Window Гісторыя Error opening downloads folder Download Window Немагчыма адчыніць папку запампованых файлаў Paste WebPositive Window Уставіць +Double-click or middle-click to open new tab. Tab Manager Скарыстайце сярэдню кнопку ці падвойны клік каб адкрыць новы таб. +Proxy username: Settings Window Імя карыстальніка проксі: Settings Settings Window Наладкі %seconds seconds left Download Window Засталося %seconds секунд Confirmation WebPositive Window Пацверджанне @@ -41,6 +43,7 @@ Quit WebPositive Window Выйсці Full screen WebPositive Window Поўнаэкранны рэжым Open download error Download Window Немагчыма адкрыць спампаваны файл Standard font: Settings Window Звычайны шрыфт: +Find previous occurrence of search terms WebPositive Window find bar previous button tooltip Знайсці папярэдні выпадак таго што шукаеце Restart Download Window Перазапусціць Proxy server Settings Window Проксі-сервер Open containing folder Download Window Адкрыць паку з гэтым файлам @@ -58,6 +61,7 @@ Cut WebPositive Window Выразаць Bookmark this page WebPositive Window Дадаць гэтую старонку ў закладкі There was an error trying to show the Bookmarks folder.\n\nError: %error WebPositive Window Don't translate variable %error Памылка падчас апрацоўкі папкі закладак.\n\nПамылка: %error Open downloads folder Download Window Адкрыць папку спамповак +Proxy password: Settings Window Пароль проксі: Number of days to keep links in History menu: Settings Window Выдаляць спасылкі з гісторыі пасля [дзён]: Hide Download Window Схаваць Reset size WebPositive Window Вярнуць памер @@ -67,6 +71,7 @@ There was an error retrieving the bookmark folder.\n\nError: %error WebPositive Over 1 day left Download Window Засталося болей 1 дня Downloads WebPositive Window Спампоўкі Requesting %url WebPositive Window Запыт да %url +Find next occurrence of search terms WebPositive Window find bar next button tooltip Знайсці наступны выпадак таго, што шукаеце Apply Settings Window Ужыць Bookmark info WebPositive Window Інфа пра закладку Size: Font Selection view Памер: @@ -80,6 +85,7 @@ Open blank page Settings Window Адчыніць пустую старонку New tabs: Settings Window Новыя ўкаладкі: Cancel WebPositive Window Скасаваць Open all WebPositive Window Адчыніць усе +Proxy server requires authentication Settings Window Проксі сервер патрабуе ідэнтыфікацыі Clear URL Bar Ачысьціць Cut URL Bar Выразаць Clear WebPositive Window Ачысьціць diff --git a/data/catalogs/apps/webpositive/de.catkeys b/data/catalogs/apps/webpositive/de.catkeys index 0b35527229..ff637e4bd7 100644 --- a/data/catalogs/apps/webpositive/de.catkeys +++ b/data/catalogs/apps/webpositive/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-WebPositive 3577331897 +1 german x-vnd.Haiku-WebPositive 1786411139 Show home button Settings Window Home-Symbol anzeigen Username: Authentication Panel Benutzername: Copy URL to clipboard Download Window Adresse kopieren @@ -16,6 +16,7 @@ Start page: Settings Window Startseite: History WebPositive Window Verlauf Error opening downloads folder Download Window Fehler beim Öffnen des Download-Ordners Paste WebPositive Window Einfügen +Double-click or middle-click to open new tab. Tab Manager Doppel- oder Mittelklick, um neuen Reiter zu öffnen. Proxy username: Settings Window Proxy-Nutzername: Settings Settings Window Einstellungen %seconds seconds left Download Window Noch %seconds Sekunden diff --git a/data/catalogs/apps/webpositive/fr.catkeys b/data/catalogs/apps/webpositive/fr.catkeys index 979bd1f036..74bff6b9c8 100644 --- a/data/catalogs/apps/webpositive/fr.catkeys +++ b/data/catalogs/apps/webpositive/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-WebPositive 3577331897 +1 french x-vnd.Haiku-WebPositive 1786411139 Show home button Settings Window Afficher le bouton de la page d'accueil Username: Authentication Panel Utilisateur : Copy URL to clipboard Download Window Copier l'URL dans le presse-papiers @@ -16,6 +16,7 @@ Start page: Settings Window Page de départ : History WebPositive Window Historique Error opening downloads folder Download Window Impossible d'ouvrir le dossier de téléchargement Paste WebPositive Window Coller +Double-click or middle-click to open new tab. Tab Manager Double-cliquez ou cliquez au milieu pour ouvrir un nouvel onglet. Proxy username: Settings Window Nom d'utilisateur du serveur mandataire : Settings Settings Window Réglages %seconds seconds left Download Window %seconds secondes restantes diff --git a/data/catalogs/apps/webpositive/hu.catkeys b/data/catalogs/apps/webpositive/hu.catkeys index 1d6c6f88b2..4d588c14bf 100644 --- a/data/catalogs/apps/webpositive/hu.catkeys +++ b/data/catalogs/apps/webpositive/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Haiku-WebPositive 3577331897 +1 hungarian x-vnd.Haiku-WebPositive 1786411139 Show home button Settings Window Kezdőlap-gomb megjelenítése Username: Authentication Panel Felhasználónév: Copy URL to clipboard Download Window Cím másolása a vágólapra @@ -16,6 +16,7 @@ Start page: Settings Window Kezdőlap: History WebPositive Window Előzmény Error opening downloads folder Download Window Hiba történt a letöltések mappa megnyitásakor Paste WebPositive Window Beillesztés +Double-click or middle-click to open new tab. Tab Manager Új fül dupla kattintással vagy az egér középső gombjával. Proxy username: Settings Window Felhasználónév a proxyhoz: Settings Settings Window Beállítások %seconds seconds left Download Window %seconds másodperc van hátra diff --git a/data/catalogs/apps/webpositive/ja.catkeys b/data/catalogs/apps/webpositive/ja.catkeys index 66881f1190..8fdc85456c 100644 --- a/data/catalogs/apps/webpositive/ja.catkeys +++ b/data/catalogs/apps/webpositive/ja.catkeys @@ -1,4 +1,4 @@ -1 japanese x-vnd.Haiku-WebPositive 3577331897 +1 japanese x-vnd.Haiku-WebPositive 1786411139 Show home button Settings Window ホームボタンを表示する Username: Authentication Panel ユーザー名: Copy URL to clipboard Download Window URL をクリップボードにコピー @@ -16,6 +16,7 @@ Start page: Settings Window スタートページ: History WebPositive Window 履歴 Error opening downloads folder Download Window ダウンロードフォルダーを開く際にエラーが発生しました Paste WebPositive Window 貼り付け +Double-click or middle-click to open new tab. Tab Manager ダブルクリックまたは中央ボタンクリックで新しいタブを開く Proxy username: Settings Window ユーザー名: Settings Settings Window 設定 %seconds seconds left Download Window 残り %seconds 秒 diff --git a/data/catalogs/apps/webpositive/pt_BR.catkeys b/data/catalogs/apps/webpositive/pt_BR.catkeys index f0c9dbb99d..31ce787a2f 100644 --- a/data/catalogs/apps/webpositive/pt_BR.catkeys +++ b/data/catalogs/apps/webpositive/pt_BR.catkeys @@ -1,4 +1,4 @@ -1 portuguese (brazil) x-vnd.Haiku-WebPositive 3577331897 +1 portuguese (brazil) x-vnd.Haiku-WebPositive 1786411139 Show home button Settings Window Exibir botão home Username: Authentication Panel Nome de Usuário: Copy URL to clipboard Download Window Copiar URL para a área de transferência @@ -16,6 +16,7 @@ Start page: Settings Window Página inicial: History WebPositive Window Histórico Error opening downloads folder Download Window Erro ao abrir pasta de itens baixados Paste WebPositive Window Colar +Double-click or middle-click to open new tab. Tab Manager Clique duas vezes ou com o botão do meio do mouse para abrir uma nova guia. Proxy username: Settings Window Nome de usuário do proxy: Settings Settings Window Definições %seconds seconds left Download Window %seconds segundos restantes diff --git a/data/catalogs/kits/be.catkeys b/data/catalogs/kits/be.catkeys index f8f9f5fea6..a13d2b3acf 100644 --- a/data/catalogs/kits/be.catkeys +++ b/data/catalogs/kits/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-libbe 677628532 +1 belarusian x-vnd.Haiku-libbe 3504008668 gamma AboutWindow гамма beta AboutWindow бэта %3.2f GiB StringForSize %3.2f ГіБ @@ -14,9 +14,11 @@ alpha AboutWindow альфа Error PrintJob Памылка No Pages to print! PrintJob Няма старонак для друку! All Rights Reserved. AboutWindow Усе правы захаваныя. +About %app% AboutWindow Пра %app% OK Dragger ОК OK PrintJob ОК Green: ColorControl Зялёны: +Ok AboutWindow Добра Version history: AboutWindow Гісторыя версій: Remove replicant Dragger Выдаліць рэпліканта OK ZombieReplicantView ОК diff --git a/data/catalogs/kits/de.catkeys b/data/catalogs/kits/de.catkeys index c790fa4bff..dddbaa4932 100644 --- a/data/catalogs/kits/de.catkeys +++ b/data/catalogs/kits/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-libbe 677628532 +1 german x-vnd.Haiku-libbe 3504008668 gamma AboutWindow Gamma beta AboutWindow Beta %3.2f GiB StringForSize %3.2f GiB @@ -14,9 +14,11 @@ alpha AboutWindow Alpha Error PrintJob Fehler No Pages to print! PrintJob Keine Seiten zu drucken! All Rights Reserved. AboutWindow Alle Rechte vorbehalten. +About %app% AboutWindow Über %app% OK Dragger OK OK PrintJob OK Green: ColorControl Grün: +Ok AboutWindow OK Version history: AboutWindow Historie: Remove replicant Dragger Replikant entfernen OK ZombieReplicantView OK diff --git a/data/catalogs/kits/fr.catkeys b/data/catalogs/kits/fr.catkeys index 9b5a0eebab..01c883a697 100644 --- a/data/catalogs/kits/fr.catkeys +++ b/data/catalogs/kits/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-libbe 677628532 +1 french x-vnd.Haiku-libbe 3504008668 gamma AboutWindow gamma beta AboutWindow bêta %3.2f GiB StringForSize %3.2f Gio @@ -14,9 +14,11 @@ alpha AboutWindow alpha Error PrintJob Erreur No Pages to print! PrintJob Aucune page à imprimer ! All Rights Reserved. AboutWindow Tous droits réservés. +About %app% AboutWindow À propos de %app% OK Dragger OK OK PrintJob OK Green: ColorControl Vert : +Ok AboutWindow Ok Version history: AboutWindow Historique des versions : Remove replicant Dragger Enlever le réplicant OK ZombieReplicantView OK diff --git a/data/catalogs/kits/hu.catkeys b/data/catalogs/kits/hu.catkeys index 55d05b4ea8..fb7793f233 100644 --- a/data/catalogs/kits/hu.catkeys +++ b/data/catalogs/kits/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Haiku-libbe 677628532 +1 hungarian x-vnd.Haiku-libbe 3504008668 gamma AboutWindow gamma beta AboutWindow béta %3.2f GiB StringForSize %3.2f GB @@ -9,14 +9,16 @@ Version AboutWindow Verzió Cannot create the replicant for \"%description\".\n%error ZombieReplicantView Nem lehet replikánst létrehozni ehhez: %description.\n%error Copy TextView Másolás %3.2f KiB StringForSize %3.2f KB -%d bytes StringForSize %Ld byte +%d bytes StringForSize %d bájt alpha AboutWindow alfa Error PrintJob Hiba No Pages to print! PrintJob Nincs nyomtatható oldal! All Rights Reserved. AboutWindow Minden jog fenntartva. +About %app% AboutWindow %app% névjegye OK Dragger Rendben OK PrintJob Rendben Green: ColorControl Zöld: +Ok AboutWindow Rendben Version history: AboutWindow Előző verziók: Remove replicant Dragger Replikáns eltávolítása OK ZombieReplicantView Rendben diff --git a/data/catalogs/kits/ru.catkeys b/data/catalogs/kits/ru.catkeys index 81c800201e..b89ce455e2 100644 --- a/data/catalogs/kits/ru.catkeys +++ b/data/catalogs/kits/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Haiku-libbe 677628532 +1 russian x-vnd.Haiku-libbe 3504008668 gamma AboutWindow гамма beta AboutWindow бета %3.2f GiB StringForSize %3.2f ГБ @@ -14,9 +14,11 @@ alpha AboutWindow альфа Error PrintJob Ошибка No Pages to print! PrintJob Нет страниц для печати All Rights Reserved. AboutWindow Все права защищены. +About %app% AboutWindow О программе… OK Dragger ОК OK PrintJob ОК Green: ColorControl Зеленый: +Ok AboutWindow Ок Version history: AboutWindow История версий: Remove replicant Dragger Удалить репликант OK ZombieReplicantView ОК diff --git a/data/catalogs/kits/textencoding/ru.catkeys b/data/catalogs/kits/textencoding/ru.catkeys index 504f1d9dcc..df5cd93b0c 100644 --- a/data/catalogs/kits/textencoding/ru.catkeys +++ b/data/catalogs/kits/textencoding/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Haiku-libtextencoding 3062073902 +1 russian x-vnd.Haiku-libtextencoding 1525027211 ISO Greek textencodings ISO Греческая ISO South European textencodings ISO Южноевропейская Chinese Big5 textencodings Китайская Big5 @@ -7,6 +7,7 @@ ISO Arabic textencodings ISO Арабская ISO Latin 9 textencodings ISO Latin 9 Japanese Shift JIS textencodings Японская Shift JIS DOS Cyrillic textencodings DOS Кириллица +Windows Central European (CP 1250) textencodings Windows Центральная Европа (CP 1250) Windows Cyrillic (CP 1251) textencodings Windows Кириллица (CP 1251) Japanese EUC textencodings Японская EUC Unicode textencodings Юникод diff --git a/data/catalogs/kits/tracker/be.catkeys b/data/catalogs/kits/tracker/be.catkeys index b561a32c54..c356a1e922 100644 --- a/data/catalogs/kits/tracker/be.catkeys +++ b/data/catalogs/kits/tracker/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-libtracker 1638733886 +1 belarusian x-vnd.Haiku-libtracker 1762695842 common B_COMMON_DIRECTORY агульны OK WidgetAttributeText ОК Icon view VolumeWindow Від іконак @@ -74,7 +74,7 @@ Arrange by ContainerWindow Сартаваць па Mount server error AutoMounterSettings Памылка сервера мантавання Search FindPanel Пошук Preparing to empty Trash… StatusWindow Падрыхтоўка да ачысткі Сметніцы… -You cannot put the selected item(s) into the trash. FSUtils Немагчыма змясціць абраныя элементы ў сметніцу. +You cannot put the selected item(s) into the trash. FSUtils Немагчыма змясціць абраны(я) элемент(ы) ў сметніцу. Disks Model Дыскі Create link ContainerWindow Стварыць спасылку develop B_COMMON_DEVELOP_DIRECTORY распрацоўка @@ -143,6 +143,7 @@ Add-ons ContainerWindow Дапаўненні Edit templates… TemplatesMenu Правіць шаблоны… Finish: %time - Over %finishtime left StatusWindow Завяршэнне: %time - Засталося каля %finishtime An item named \"%name\" already exists in this folder. Would you like to replace it with the symbolic link you are creating? FSUtils Элемент \"%name\" у гэтым каталозе ўжо існуе. Ці жадаеце замяніць яго ствараемай спасылкай? +Fewer options FindPanel Менш наладак Sorry, there is not enough free space on the destination volume to copy the selection. FSUtils Прабачце, не хапае месца на томе прызначэння для капіявання выбранага. Could not open \"%document\" with application \"%app\" (%error). FSUtils Нельга адкрыць \"%document\" праграмай \"%app\" (%error). Sorry, saving more than one item is not allowed. FilePanelPriv Прабачце, захаванне больш чым аднаго элемента не дазволена. @@ -236,6 +237,7 @@ Temporary FindPanel Часовы Version OpenWithWindow Версія Default application InfoWindow Прадвызначаная праграма Preparing to copy items… StatusWindow Падрыхтоўка да капіявання… +Save query as template… FindPanel Захаваць запыт як шаблон… Show folder location in title tab SettingsView Паказваць адрас каталога у імені ўкладкі Proceed FSUtils Далей Some items already exist in this folder with the same names as the items you are %verb.\n \nWould you like to replace them with the ones you are %verb or be prompted for each one? FSUtils Некаторыя элементы ужо існуюць у гэтым каталозе з тымі ж імёнамі, як і ў элементаў, якія вы %verb.\n \nЖадаеце замяніць іх тымі, што вы %verb, або вырашыць асобна для кожнага элемента? @@ -334,6 +336,7 @@ The specified name is already used as the name of a folder. Please choose anothe Clean up ContainerWindow Прыбрацца after FindPanel пасля Select… QueryContainerWindow Выбраць… +More options FindPanel Больш параметраў link FSUtils filename link спасылка At %func \nfind_directory() failed. \nReason: %error TrackerInitialState У %func \nfind_directory() не ўдалося. \nПрычына: %error The specified name is illegal. Please choose another name. FilePanelPriv Пазначанае імя недапушчальна. Калі ласка, выберыце іншае. @@ -445,6 +448,7 @@ contains FindPanel месціць Relation OpenWithWindow Адносіны Open FilePanelPriv Адкрыць Mount DeskWindow Змантаваць +Recent queries FindPanel Папярэднія запыты Mount ContainerWindow Змантаваць %capacity (%used used -- %free free) InfoWindow %capacity (%used выкарыстана -- %free свабодна) Cancel FSClipBoard Адмена diff --git a/data/catalogs/kits/tracker/de.catkeys b/data/catalogs/kits/tracker/de.catkeys index c617eafbe9..e830192c1c 100644 --- a/data/catalogs/kits/tracker/de.catkeys +++ b/data/catalogs/kits/tracker/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-libtracker 1638733886 +1 german x-vnd.Haiku-libtracker 1762695842 common B_COMMON_DIRECTORY Allgemein OK WidgetAttributeText OK Icon view VolumeWindow Icon-Ansicht @@ -143,6 +143,7 @@ Add-ons ContainerWindow Add-ons Edit templates… TemplatesMenu Vorlagen bearbeiten… Finish: %time - Over %finishtime left StatusWindow Fertig: %time - Noch über %finishtime An item named \"%name\" already exists in this folder. Would you like to replace it with the symbolic link you are creating? FSUtils Ein Objekt mit dem Namen \"%name\" existiert bereits in diesem Ordner. Soll es mit der Verknüpfung ersetzt werden, die gerade erstellt werden soll? +Fewer options FindPanel Weniger Optionen Sorry, there is not enough free space on the destination volume to copy the selection. FSUtils Es ist nicht genug Speicherplatz auf dem Zieldatenträger frei, um die Auswahl zu kopieren. Could not open \"%document\" with application \"%app\" (%error). FSUtils \"%document\" konnte nicht mit der Anwendung \"%app\" geöffnet werden (%error). Sorry, saving more than one item is not allowed. FilePanelPriv Es kann leider immer nur ein einzelnes Objekt gespeichert werden. @@ -236,6 +237,7 @@ Temporary FindPanel Temporär Version OpenWithWindow Version Default application InfoWindow Standardanwendung Preparing to copy items… StatusWindow Kopieren wird vorbereitet… +Save query as template… FindPanel Query als Vorlage speichern… Show folder location in title tab SettingsView Ordnerpfad im Fenstertitel zeigen Proceed FSUtils Fortfahren Some items already exist in this folder with the same names as the items you are %verb.\n \nWould you like to replace them with the ones you are %verb or be prompted for each one? FSUtils Manche Objekte in diesem Ordner heißen genauso wie Objekte, die gerade %verb werden sollen.\n\nSollen sie alle ersetzt werden, oder soll jedes Mal einzeln nachgefragt werden? @@ -334,6 +336,7 @@ The specified name is already used as the name of a folder. Please choose anothe Clean up ContainerWindow Icons ausrichten after FindPanel nach Select… QueryContainerWindow Auswählen… +More options FindPanel Weitere Optionen link FSUtils filename link Verknüpfung At %func \nfind_directory() failed. \nReason: %error TrackerInitialState Bei %func \nfind_directory() fehlgeschlagen \nGrund: %error The specified name is illegal. Please choose another name. FilePanelPriv Der angegebene Name ist nicht gültig. Bitte einen anderen wählen. @@ -445,6 +448,7 @@ contains FindPanel enthält Relation OpenWithWindow Beziehung Open FilePanelPriv Öffnen Mount DeskWindow Einhängen +Recent queries FindPanel Letzte Queries Mount ContainerWindow Einhängen %capacity (%used used -- %free free) InfoWindow %capacity (%used benutzt -- %free frei) Cancel FSClipBoard Abbrechen diff --git a/data/catalogs/kits/tracker/fr.catkeys b/data/catalogs/kits/tracker/fr.catkeys index 6e90007ccf..ed3eab3706 100644 --- a/data/catalogs/kits/tracker/fr.catkeys +++ b/data/catalogs/kits/tracker/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-libtracker 1638733886 +1 french x-vnd.Haiku-libtracker 1762695842 common B_COMMON_DIRECTORY commun OK WidgetAttributeText OK Icon view VolumeWindow Vue en icônes @@ -143,6 +143,7 @@ Add-ons ContainerWindow Extensions Edit templates… TemplatesMenu Éditer les modèles… Finish: %time - Over %finishtime left StatusWindow Fin : %time - il reste plus de %finishtime An item named \"%name\" already exists in this folder. Would you like to replace it with the symbolic link you are creating? FSUtils Un élément nommé « %name » existe déjà dans ce dossier. Voulez vous le remplacer par le lien symbolique que vous créez ? +Fewer options FindPanel Moins d'options Sorry, there is not enough free space on the destination volume to copy the selection. FSUtils Désolé, il n'y a pas assez d'espace libre dans le volume cible pour copier la sélection. Could not open \"%document\" with application \"%app\" (%error). FSUtils Impossible d'ouvrir « %document » avec l'application « %app » (%error). Sorry, saving more than one item is not allowed. FilePanelPriv Désolé, il n'est pas permis de sauvegarder plus d'un élément. @@ -236,6 +237,7 @@ Temporary FindPanel Temporaire Version OpenWithWindow Version Default application InfoWindow Application par défaut Preparing to copy items… StatusWindow Copie des éléments en préparation… +Save query as template… FindPanel Enregistrer le modèle de la requête… Show folder location in title tab SettingsView Afficher l'emplacement du dossier dans la barre de titre Proceed FSUtils Procéder Some items already exist in this folder with the same names as the items you are %verb.\n \nWould you like to replace them with the ones you are %verb or be prompted for each one? FSUtils Plusieurs éléments de ce dossier portent les mêmes noms que des éléments que vous êtes en train de %verb.\n\nVoulez-vous les remplacer par ceux que vous êtes en train de %verb ou voulez-vous qu'une confirmation vous soit demandée pour chacun d'eux ? @@ -334,6 +336,7 @@ The specified name is already used as the name of a folder. Please choose anothe Clean up ContainerWindow Nettoyer after FindPanel après Select… QueryContainerWindow Sélectionner… +More options FindPanel Plus d'options link FSUtils filename link lien At %func \nfind_directory() failed. \nReason: %error TrackerInitialState Dans %func\nfind_directory() a échoué.\nMotif : %error The specified name is illegal. Please choose another name. FilePanelPriv Le nom indiqué n'est pas valide. Veuillez choisir un autre nom. @@ -445,6 +448,7 @@ contains FindPanel contient Relation OpenWithWindow Relation Open FilePanelPriv Ouvrir Mount DeskWindow Monter +Recent queries FindPanel Requêtes récentes Mount ContainerWindow Monter %capacity (%used used -- %free free) InfoWindow %capacity (%used utilisés -- %free libres) Cancel FSClipBoard Annuler diff --git a/data/catalogs/kits/tracker/hu.catkeys b/data/catalogs/kits/tracker/hu.catkeys index 65ea2318a7..eedd9be766 100644 --- a/data/catalogs/kits/tracker/hu.catkeys +++ b/data/catalogs/kits/tracker/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Haiku-libtracker 1638733886 +1 hungarian x-vnd.Haiku-libtracker 1762695842 common B_COMMON_DIRECTORY Közös OK WidgetAttributeText Rendben Icon view VolumeWindow Ikon nézet @@ -143,6 +143,7 @@ Add-ons ContainerWindow Kiegészítők Edit templates… TemplatesMenu Sablonok szerkesztése… Finish: %time - Over %finishtime left StatusWindow Befejezés: %time - Több, mint %finishtime van hátra An item named \"%name\" already exists in this folder. Would you like to replace it with the symbolic link you are creating? FSUtils Már van ebben a mappában egy elem ezzel a névvel: %name. Szeretné felülírni a most elkészítendő szimbolikus hivatkozást? +Fewer options FindPanel Kevesebb opció Sorry, there is not enough free space on the destination volume to copy the selection. FSUtils Sajnáljuk, de nincs elég hely a kiválasztott lemezen a másoláshoz. Could not open \"%document\" with application \"%app\" (%error). FSUtils Nem sikerült megnyitni a dokumentumot (%document) a programmal (%app).\n\t%error Sorry, saving more than one item is not allowed. FilePanelPriv Sajnálom, de egyszerre csak egy elemet lehet elmenteni. @@ -236,6 +237,7 @@ Temporary FindPanel Ideiglenes megőrzés Version OpenWithWindow Verzió Default application InfoWindow Alapértelmezett program Preparing to copy items… StatusWindow Felkészülés az elemek másolására… +Save query as template… FindPanel Keresés mentése sablonként… Show folder location in title tab SettingsView Mappa helyének megjelenítése a fülön Proceed FSUtils Folytatás Some items already exist in this folder with the same names as the items you are %verb.\n \nWould you like to replace them with the ones you are %verb or be prompted for each one? FSUtils A mappában már néhány elem neve megyegyezik azzal, amit Ön %verb akar.\n\nSzeretné lecserélni öket azokkal amiket ön szeretne most %verb, vagy minden elemnél kérdezzük meg? @@ -334,6 +336,7 @@ The specified name is already used as the name of a folder. Please choose anothe Clean up ContainerWindow Rendrakás after FindPanel utána Select… QueryContainerWindow Kijelölés… +More options FindPanel További opciók link FSUtils filename link hivatkozás At %func \nfind_directory() failed. \nReason: %error TrackerInitialState Ennél: %func \nsikertelen volt a find_directory(). \nOka: %error The specified name is illegal. Please choose another name. FilePanelPriv A megadott név szabálytalan. Kérjük válasszon egy másik nevet. @@ -445,6 +448,7 @@ contains FindPanel tartalmazza Relation OpenWithWindow Kapcsolat Open FilePanelPriv Megnyitás Mount DeskWindow Csatolás +Recent queries FindPanel Előző keresések Mount ContainerWindow Csatolás %capacity (%used used -- %free free) InfoWindow %capacity (%used használt -- %free szabad) Cancel FSClipBoard Mégse diff --git a/data/catalogs/kits/tracker/pl.catkeys b/data/catalogs/kits/tracker/pl.catkeys index e57b71be87..db4bae2da4 100644 --- a/data/catalogs/kits/tracker/pl.catkeys +++ b/data/catalogs/kits/tracker/pl.catkeys @@ -1,4 +1,4 @@ -1 polish x-vnd.Haiku-libtracker 4112182761 +1 polish x-vnd.Haiku-libtracker 4236144717 common B_COMMON_DIRECTORY wspólny OK WidgetAttributeText OK Icon view VolumeWindow Widok ikon @@ -142,6 +142,7 @@ Add-ons ContainerWindow Wtyczki Edit templates… TemplatesMenu Edytuj szablony… Finish: %time - Over %finishtime left StatusWindow Koniec: %time - Pozostało %finishtime An item named \"%name\" already exists in this folder. Would you like to replace it with the symbolic link you are creating? FSUtils Objekt o nazwie \"%name\" już istnieje w tym folderu. Zamienić na skrót symboliczny? +Fewer options FindPanel Mniej opcji Sorry, there is not enough free space on the destination volume to copy the selection. FSUtils Nie wystarczająca ilość pamięci w miejscu docelowym by wykonać kopiowanie. Could not open \"%document\" with application \"%app\" (%error). FSUtils Nie można otworzyć \"%document\" z aplikacją \"%app\" (%error). Sorry, saving more than one item is not allowed. FilePanelPriv Można zapisać tylko jeden plik naraz. @@ -234,6 +235,7 @@ Temporary FindPanel Tymczasowy Version OpenWithWindow Wersja Default application InfoWindow Domyślna aplikacja Preparing to copy items… StatusWindow Przygotowanie do kopiowania elementów… +Save query as template… FindPanel Zapisz zapytanie jako szablon… Show folder location in title tab SettingsView Pokaż lokacje folderu na pasku Proceed FSUtils Kontynuuj Some items already exist in this folder with the same names as the items you are %verb.\n \nWould you like to replace them with the ones you are %verb or be prompted for each one? FSUtils Niektóre obiekty już istnieją w tym folderze o nazwach identycznych co te które probujesz %verb.\n \nCzy chcesz je zamienić z tymi które próbujesz %verb czy wolisz być pytany o każdy z nich? @@ -332,6 +334,7 @@ The specified name is already used as the name of a folder. Please choose anothe Clean up ContainerWindow Wyczyść after FindPanel po Select… QueryContainerWindow Wybierz… +More options FindPanel Więcej opcji link FSUtils filename link Skrót At %func \nfind_directory() failed. \nReason: %error TrackerInitialState W %func \nfind_directory() nie powiódł się. \nPowód: %error The specified name is illegal. Please choose another name. FilePanelPriv Podana nazwa jest niedozwolona. Proszę wybrać inną nazwę. @@ -443,6 +446,7 @@ contains FindPanel zawiera Relation OpenWithWindow Relacje Open FilePanelPriv Otwórz Mount DeskWindow Zamontuj +Recent queries FindPanel Ostatnie zapytania Mount ContainerWindow Zamontuj %capacity (%used used -- %free free) InfoWindow %capacity (%used zajęte -- %free wolne) Cancel FSClipBoard Anuluj diff --git a/data/catalogs/kits/tracker/ru.catkeys b/data/catalogs/kits/tracker/ru.catkeys index 21b9053e5c..1cac91d33d 100644 --- a/data/catalogs/kits/tracker/ru.catkeys +++ b/data/catalogs/kits/tracker/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Haiku-libtracker 1638733886 +1 russian x-vnd.Haiku-libtracker 1762695842 common B_COMMON_DIRECTORY Общие OK WidgetAttributeText ОК Icon view VolumeWindow Большие значки @@ -143,6 +143,7 @@ Add-ons ContainerWindow Дополнения Edit templates… TemplatesMenu Изменить шаблоны… Finish: %time - Over %finishtime left StatusWindow Окончание: %time - Осталось более %finishtime An item named \"%name\" already exists in this folder. Would you like to replace it with the symbolic link you are creating? FSUtils Объект с именем \"%name\" уже существует в этой папке. Заменить его ссылкой, которую вы создаёте? +Fewer options FindPanel Меньше опций Sorry, there is not enough free space on the destination volume to copy the selection. FSUtils Извините, но на принимающем разделе недостаточно свободного места для копирования выделенных файлов. Could not open \"%document\" with application \"%app\" (%error). FSUtils Невозможно открыть \"%document\" приложением \"%app\" (%error). Sorry, saving more than one item is not allowed. FilePanelPriv Извините, сохранение более одного файла недопустимо. @@ -236,6 +237,7 @@ Temporary FindPanel Временный запрос Version OpenWithWindow Версия Default application InfoWindow приложении по умолчанию Preparing to copy items… StatusWindow Подготовка к копированию файлов… +Save query as template… FindPanel Сохранить запрос как шаблон… Show folder location in title tab SettingsView Показывать путь папки в заголовке окна Proceed FSUtils Исправить Some items already exist in this folder with the same names as the items you are %verb.\n \nWould you like to replace them with the ones you are %verb or be prompted for each one? FSUtils Некоторые объекты с такими же именами, которые вы %verb, уже существуют в этой папке.\n \nЗаменить их теми, которые вы %verb или спрашивать для каждого объекта? @@ -334,6 +336,7 @@ The specified name is already used as the name of a folder. Please choose anothe Clean up ContainerWindow Выстроить after FindPanel после Select… QueryContainerWindow Выделить… +More options FindPanel Больше опций link FSUtils filename link ссылка At %func \nfind_directory() failed. \nReason: %error TrackerInitialState Не удалось выполнить %func в find_directory(). \nПричина: %error The specified name is illegal. Please choose another name. FilePanelPriv Введённое имя недопустимо. Введите какое-нибудь другое. @@ -445,6 +448,7 @@ contains FindPanel содержит Relation OpenWithWindow Возможности Open FilePanelPriv Открыть Mount DeskWindow Подключить +Recent queries FindPanel Недавние запросы Mount ContainerWindow Подключить %capacity (%used used -- %free free) InfoWindow %capacity (%used занято -- %free свободно) Cancel FSClipBoard Отмена diff --git a/data/catalogs/preferences/appearance/pl.catkeys b/data/catalogs/preferences/appearance/pl.catkeys index c865e9c30c..b3e9b9e529 100644 --- a/data/catalogs/preferences/appearance/pl.catkeys +++ b/data/catalogs/preferences/appearance/pl.catkeys @@ -1,4 +1,4 @@ -1 polish x-vnd.Haiku-Appearance 556979190 +1 polish x-vnd.Haiku-Appearance 1475577782 Plain font: Font view Zwykła czcionka: Control highlight Colors tab Podkreślenie kontrolki Control border Colors tab Obramowanie kontrolki @@ -32,7 +32,9 @@ Document text Colors tab Tekst dokumentu Navigation pulse Colors tab Puls nawigacji Selected menu item text Colors tab Tekst zaznaczonego elementu menu Menu background Colors tab Tło menu +List background Colors tab Tło listy OK DecorSettingsView OK +Control mark Colors tab Znak sterujący Size: Font Selection view Rozmiar: Selected list item background Colors tab Tło zaznaczonego elementu listy Panel background Colors tab Tło panelu @@ -40,6 +42,7 @@ Menu font: Font view Czcionka menu: Colors APRWindow Kolory Control background Colors tab Tło kontrolki Inactive window tab Colors tab Nieaktywna zakładka okna +List item text Colors tab Tekst elementu listy Appearance System name Wygląd Fixed font: Font view Czcionka o stałej szerokości: The quick brown fox jumps over the lazy dog. Font Selection view Don't translate this literally ! Use a phrase showing all chars from A to Z. Koń i żółw grali w kości z piękną ćmą u źródła. diff --git a/data/catalogs/preferences/appearance/ru.catkeys b/data/catalogs/preferences/appearance/ru.catkeys index 1bb3f6ddbd..ba5eccd9d6 100644 --- a/data/catalogs/preferences/appearance/ru.catkeys +++ b/data/catalogs/preferences/appearance/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Haiku-Appearance 2993758435 +1 russian x-vnd.Haiku-Appearance 727801787 Plain font: Font view Простой шрифт: Control highlight Colors tab Подсветка элемента Control border Colors tab Граница элемента @@ -50,6 +50,7 @@ The quick brown fox jumps over the lazy dog. Font Selection view Don't translate %decorName\n\nAuthors:\n\t%decorAuthors\n\nURL: %decorURL\nLicense: %decorLic\n\n%decorDesc\n DecorSettingsView %decorName\n\nАвторы:\n\t%decorAuthors\n\nURL: %decorURL\nЛицензия: %decorLic\n\n%decorDesc\n Reduce colored edges filter strength: AntialiasingSettingsView Фильтрация цветных краев: Subpixel based anti-aliasing in combination with glyph hinting is not available in this build of Haiku to avoid possible patent issues. To enable this feature, you have to build Haiku yourself and enable certain options in the libfreetype configuration header. AntialiasingSettingsView Субпиксельное сглаживание в комбинации с уточнением глифов недоступно в этой сборке Haiku во избежание возможных патентных проблем. Для включения этой возможности вам придется собрать Haiku самостоятельно, включив особые опции в заголовке конфигурации libfreetype. +Scroll bar thumb Colors tab Ползунок прокрутки Control text Colors tab Текст элемента Single: DecorSettingsView Одинарный: Tooltip text Colors tab Текст подсказки diff --git a/data/catalogs/preferences/datatranslations/pt_BR.catkeys b/data/catalogs/preferences/datatranslations/pt_BR.catkeys index 39322220f3..dacbc4026e 100644 --- a/data/catalogs/preferences/datatranslations/pt_BR.catkeys +++ b/data/catalogs/preferences/datatranslations/pt_BR.catkeys @@ -6,7 +6,7 @@ Name: %s \nVersion: %ld.%ld.%ld\n\nInfo:\n%s\n\nPath:\n%s\n DataTranslations No The item '%name' does not appear to be a Translator and will not be installed. DataTranslations O item '%name' não aparenta ser um Tradutor e não será instalado. Could not install %s:\n%s DataTranslations Não foi possível instalar o %s:\n%s Use this control panel to set default values for translators, to be used when no other settings are specified by an application. DataTranslations Use este painel de controle para definir valores padrão para tradutores, a serem utilizados quando não houver outras configurações especificadas por um aplicativo. -An item named '%name' already exists in the Translators folder! Shall the existing translator be overwritten? DataTranslations Um item de nome '%name' já existe na pasta de Tradutores! Deve o tradutor existente ser sobrescrito? +An item named '%name' already exists in the Translators folder! Shall the existing translator be overwritten? DataTranslations Um item denominado '%name' já existe na pasta de Tradutores! Deve o tradutor existente ser sobrescrito? DataTranslations - Note DataTranslations Traduções de Dados - Nota Overwrite DataTranslations Sobrescrever Info: DataTranslations Informação: diff --git a/data/catalogs/preferences/network/be.catkeys b/data/catalogs/preferences/network/be.catkeys index 94c80730c5..ec36652af8 100644 --- a/data/catalogs/preferences/network/be.catkeys +++ b/data/catalogs/preferences/network/be.catkeys @@ -1,23 +1,27 @@ -1 belarusian x-vnd.Haiku-Network 781877986 +1 belarusian x-vnd.Haiku-Network 1341378870 Choose automatically EthernetSettingsView Выбіраць аўтаматычна Gateway: EthernetSettingsView Шлюз: Netmask: EthernetSettingsView Маска сеткі: DHCP EthernetSettingsView DHCP DNS #2: EthernetSettingsView DNS #2: Apply EthernetSettingsView Ужыць -Netmask is invalid EthernetSettingsView Няслушная маска падсеткі. +Netmask is invalid EthernetSettingsView Няслушная маска падсеткі OK EthernetSettingsView ОК DNS #1: EthernetSettingsView DNS #1: IP address: EthernetSettingsView IP адрас: Adapter: EthernetSettingsView Адаптар: Domain: EthernetSettingsView Домен: +Gateway is invalid EthernetSettingsView Шлюз несапраўдны +DNS #1 is invalid EthernetSettingsView DNS #1 некарэктны Revert EthernetSettingsView Вярнуць EthernetSettingsView <не знойдзена бесшнуравых сетак> Network System name Сетка Mode: EthernetSettingsView Рэжым: +IP address is invalid EthernetSettingsView IP адрас некарэктны Network: EthernetSettingsView Сетка: The net_server needs to run for the auto configuration! EthernetSettingsView Неабходна запусціць net_server для аўтаканфігурацыі! Disabled EthernetSettingsView Выключаны Auto-configuring failed: EthernetSettingsView Аўтаканфігурацыі не ўдалася: Static EthernetSettingsView Статычны +DNS #2 is invalid EthernetSettingsView DNS #2 некарэктны EthernetSettingsView <адаптары ня знойдзены> diff --git a/data/catalogs/preferences/network/pt_BR.catkeys b/data/catalogs/preferences/network/pt_BR.catkeys index 1c935884a0..b2e30a9c13 100644 --- a/data/catalogs/preferences/network/pt_BR.catkeys +++ b/data/catalogs/preferences/network/pt_BR.catkeys @@ -5,23 +5,23 @@ Netmask: EthernetSettingsView Máscara de rede: DHCP EthernetSettingsView DHCP DNS #2: EthernetSettingsView DNS #2: Apply EthernetSettingsView Aplicar -Netmask is invalid EthernetSettingsView Máscara de rede é inválida +Netmask is invalid EthernetSettingsView Máscara de rede inválida OK EthernetSettingsView OK DNS #1: EthernetSettingsView DNS #1: IP address: EthernetSettingsView Endereço de IP: Adapter: EthernetSettingsView Adaptador: Domain: EthernetSettingsView Domínio: -Gateway is invalid EthernetSettingsView O Gateway é inválido +Gateway is invalid EthernetSettingsView Gateway inválido DNS #1 is invalid EthernetSettingsView DNS #1 é inválido Revert EthernetSettingsView Reverter EthernetSettingsView Network System name Rede Mode: EthernetSettingsView Modo: -IP address is invalid EthernetSettingsView O endereço IP é inválido +IP address is invalid EthernetSettingsView Endereço IP inválido Network: EthernetSettingsView Rede: The net_server needs to run for the auto configuration! EthernetSettingsView É preciso abrir o net_server para efetuar a configuração automática! Disabled EthernetSettingsView Desativado Auto-configuring failed: EthernetSettingsView Auto-configuração falhou: Static EthernetSettingsView Estático -DNS #2 is invalid EthernetSettingsView DNS #2 é inválido +DNS #2 is invalid EthernetSettingsView DNS #2 inválido EthernetSettingsView diff --git a/data/catalogs/preferences/screen/pt_BR.catkeys b/data/catalogs/preferences/screen/pt_BR.catkeys index b944d2eeb0..da2c0a63f0 100644 --- a/data/catalogs/preferences/screen/pt_BR.catkeys +++ b/data/catalogs/preferences/screen/pt_BR.catkeys @@ -17,7 +17,7 @@ OK Screen OK Workspaces Screen Workspaces The screen mode could not be set:\n\t%s\n Screen O modo de tela não pode ser aceito\n\t%s\n no Screen não -Could not write VESA mode settings file:\n\t Screen Não foi possível escrever as configurações do arquivo do modo Vesa:\n\t +Could not write VESA mode settings file:\n\t Screen Não foi possível gravar o arquivo de configurações do modo VESA:\n\t Type or use the left and right arrow keys. Screen Escreva ou use as teclas de seta Warning Screen Aviso Horizonal frequency:\t%lu - %lu kHz\nVertical frequency:\t%lu - %lu Hz\n\nMaximum pixel clock:\t%g MHz Screen Frequência horizonal:\t%lu - %lu kHz\nFrequência vertical:\t%lu - %lu Hz\n\nRelógio máximo de pixel:\t%g MHz diff --git a/data/catalogs/preferences/shortcuts/pt_BR.catkeys b/data/catalogs/preferences/shortcuts/pt_BR.catkeys index ce6e89db02..5d5775c786 100644 --- a/data/catalogs/preferences/shortcuts/pt_BR.catkeys +++ b/data/catalogs/preferences/shortcuts/pt_BR.catkeys @@ -1,5 +1,5 @@ 1 portuguese (brazil) x-vnd.Haiku-Shortcuts 341885426 -Error, NULL state description?\n ShortcutsSpec Erro, descrição de estado em branco?\n +Error, NULL state description?\n ShortcutsSpec Erro, descrição de estado nulo?\n MoveMouse ShortcutsSpec Mover o Mouse OK ShortcutsWindow OK Shortcuts wasn't able to save your keyset. ShortcutsWindow O Atalhos não pode salvar sua combinação de teclas diff --git a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/be.catkeys b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/be.catkeys new file mode 100644 index 0000000000..83b4d42b07 --- /dev/null +++ b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/be.catkeys @@ -0,0 +1,33 @@ +1 belarusian x-vnd.Haiku-InterfacesAddOn 160108912 +Interface InterfaceWindow Інтэрфейс +Configure… InterfacesListView Канфігураваць… +Static IntefaceAddressView Статычны +None InterfacesListView Няма +IP: InterfacesListView IPv4 address label IP: +Status: IntefaceHardwareView Стан: +IPv6: InterfacesListView IPv6 address label IPv6: +Save InterfaceWindow Захаваць +Link speed: IntefaceHardwareView Хуткасць злучэння: +Renegotiate InterfacesAddOn Перазлучыць +The method for obtaining an IP address IntefaceAddressView Метад атрыманя IP адрасу +Your gateway IntefaceAddressView Ваш gateway +Enable InterfacesListView Дазволіць +Received: IntefaceHardwareView Атрымана: +Revert InterfaceWindow Вярнуць +connected IntefaceHardwareView злучаны +Gateway: IntefaceAddressView Брама: +Disable InterfacesListView Выключыць +Sent: IntefaceHardwareView Адаслана: +Disable InterfacesAddOn Выключыць +Configure… InterfacesAddOn Канфігураваць… +Renegotiate Address InterfacesListView Перазлучыць адрас +DHCP IntefaceAddressView DHCP +Mode: IntefaceAddressView Рэжым: +Your netmask IntefaceAddressView Маска +IP Address: IntefaceAddressView IP адрас: +Off IntefaceAddressView Адключыць +MAC address: IntefaceHardwareView MAC адрас: +Netmask: IntefaceAddressView Маска: +Your IP address IntefaceAddressView IP адрас +%llu KBytes IntefaceHardwareView %llu КБайт +disconnected IntefaceHardwareView адлучана diff --git a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/pl.catkeys b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/pl.catkeys index 323bf5c2db..b5e8025ff9 100644 --- a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/pl.catkeys +++ b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/pl.catkeys @@ -1,15 +1,23 @@ -1 polish x-vnd.Haiku-InterfacesAddOn 34473294 +1 polish x-vnd.Haiku-InterfacesAddOn 3798202204 Interface InterfaceWindow Interfejs Configure… InterfacesListView Konfiguruj… Static IntefaceAddressView Statyczny IP: InterfacesListView IPv4 address label IP: +IPv6: InterfacesListView IPv6 address label IPv6: Link speed: IntefaceHardwareView Szybkość połączenia: +Renegotiate InterfacesAddOn Negocjuj ponownie The method for obtaining an IP address IntefaceAddressView Metoda uzyskania adresu IP Your gateway IntefaceAddressView Brama Received: IntefaceHardwareView Otrzymano: +connected IntefaceHardwareView połączono +Gateway: IntefaceAddressView Brama: Sent: IntefaceHardwareView Wysłano: Configure… InterfacesAddOn Konfiguruj… +Renegotiate Address InterfacesListView Ponownie negocjuj adres +DHCP IntefaceAddressView DHCP Mode: IntefaceAddressView Tryb: -Your netmask IntefaceAddressView Maska sieci +Your netmask IntefaceAddressView Maska twojej sieci IP Address: IntefaceAddressView Adres IP: +Your IP address IntefaceAddressView Twój adres IP +%llu KBytes IntefaceHardwareView %llu kilobajtów disconnected IntefaceHardwareView odłączone diff --git a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/ru.catkeys b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/ru.catkeys new file mode 100644 index 0000000000..33fb5acd01 --- /dev/null +++ b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/ru.catkeys @@ -0,0 +1,33 @@ +1 russian x-vnd.Haiku-InterfacesAddOn 160108912 +Interface InterfaceWindow Интерфейс +Configure… InterfacesListView Настроить… +Static IntefaceAddressView Статический +None InterfacesListView Отсутствует +IP: InterfacesListView IPv4 address label IP: +Status: IntefaceHardwareView Статус: +IPv6: InterfacesListView IPv6 address label IPv6: +Save InterfaceWindow Сохранить +Link speed: IntefaceHardwareView Скорость соединения: +Renegotiate InterfacesAddOn Переполучить +The method for obtaining an IP address IntefaceAddressView Метод получения IP адреса +Your gateway IntefaceAddressView Ваш шлюз +Enable InterfacesListView Включить +Received: IntefaceHardwareView Получено: +Revert InterfaceWindow Вернуть +connected IntefaceHardwareView подключён +Gateway: IntefaceAddressView Шлюз: +Disable InterfacesListView Отключить +Sent: IntefaceHardwareView Отправлено: +Disable InterfacesAddOn Отключить +Configure… InterfacesAddOn Настроить… +Renegotiate Address InterfacesListView Переполучить адрес +DHCP IntefaceAddressView DHCP +Mode: IntefaceAddressView Режим: +Your netmask IntefaceAddressView Маска подсети +IP Address: IntefaceAddressView IP-адрес: +Off IntefaceAddressView Выключить +MAC address: IntefaceHardwareView MAC-адрес: +Netmask: IntefaceAddressView Маска подсети: +Your IP address IntefaceAddressView IP-адрес: +%llu KBytes IntefaceHardwareView %llu КБайт +disconnected IntefaceHardwareView отключён diff --git a/data/catalogs/tests/servers/app/playground/be.catkeys b/data/catalogs/tests/servers/app/playground/be.catkeys new file mode 100644 index 0000000000..81679b2e76 --- /dev/null +++ b/data/catalogs/tests/servers/app/playground/be.catkeys @@ -0,0 +1,32 @@ +1 belarusian x-vnd.Haiku-Playground 1375574837 +Line Playground Радок +Fill Playground Запоўніць +Over Playground Па над +Quit Playground Выйсці +Rect Playground Прамакутнік +Select Playground Вылучыць +Click and drag to draw an object Playground Націсніце і цягніце каб намаляваць аб'ект +Controls Playground Кіраваньне +Round rect Playground Круглы прамакутнік +Alpha: Playground Альфа: +Mode: Playground Рэжым: +Submenu Playground Падменю +Copy Playground Скапіяваць +Cancel Playground Адмена +Clear Playground Ачысьціць +Min Playground Мін +Blend Playground Змешваць +Invert Playground Інвэртаваць +Clear all drawing objects? Playground Выдаліць усе аб'екты? +Width: Playground Шырыня: +Alpha Playground Альфа +New object Playground Новы аб'ект +Test Playground Тэст +Max Playground Макс +Add Playground Дадаць +Playground System name Пляцоўка для гульняў +Erase Playground Выдаліць +File Playground Файл +Subtract Playground Адняць + Playground <абраць> +Ellipse Playground Эліпс diff --git a/data/catalogs/tests/servers/app/playground/pl.catkeys b/data/catalogs/tests/servers/app/playground/pl.catkeys index e0a34d39b4..548605ef11 100644 --- a/data/catalogs/tests/servers/app/playground/pl.catkeys +++ b/data/catalogs/tests/servers/app/playground/pl.catkeys @@ -1,5 +1,10 @@ -1 polish x-vnd.Haiku-Playground 1190349404 +1 polish x-vnd.Haiku-Playground 3331526596 Line Playground Linia +Fill Playground Wypełnienie +Over Playground Ponad +Quit Playground Zakończ +Rect Playground Prostokąt +Select Playground Wybierz Click and drag to draw an object Playground Kliknij i przeciągnij, żeby narysować obiekt Controls Playground Sterowanie Round rect Playground Zaokrąglony prostokąt diff --git a/data/catalogs/tools/translation/inspector/pt_BR.catkeys b/data/catalogs/tools/translation/inspector/pt_BR.catkeys index 5bc2d8e9f1..74c70d597a 100644 --- a/data/catalogs/tools/translation/inspector/pt_BR.catkeys +++ b/data/catalogs/tools/translation/inspector/pt_BR.catkeys @@ -1,17 +1,17 @@ 1 portuguese (brazil) x.vnd.OBOS-Inspector 2075781936 -User Translators ActiveTranslatorsWindow Tradutores do usuário +User Translators ActiveTranslatorsWindow Tradutores do Usuário No image available to save. ImageWindow Nenhuma imagem disponível para salvar. Sorry, unable to write the image file. ImageView Desculpe, não foi possível gravar o arquivo de imagem. Number of Documents: %1\n\nTranslator Used:\nName: %2\nInfo: %3\nVersion: %4\n ImageView Número de documentos: %1\n\nTradutor usado:\nNome: %2\nInformações: %3\nVersão: %4\n \nType: '%1' (%2)\nGroup: '%3' (%4)\nQuality: %5\nCapability: %6\nMIME Type: %7\nName: %8\n ImageView \nTipo: '%1' (%2)\nGrupo: '%3' (%4)\nQualidade: %5\nRecursos: %6\nTipo MIME: %7\nNome: %8\n Bummer ImageWindow Bummer -Last Page ImageWindow Última página -\nInput Formats: ImageView \nFormatos de entrada: +Last Page ImageWindow Última Página +\nInput Formats: ImageView \nFormatos de Entrada: Sorry, unable to load the image. ImageView Desculpe, não foi possível carregar a imagem. Info Win InspectorApp This is a quite narrow info window and title 'Info Win' is therefore shortened. Janela de Informação Active Translators InspectorApp Tradutores ativos Image: %1\nColor Space: %2 (%3)\nDimensions: %4 x %5\nBytes per Row: %6\nTotal Bytes: %7\n\nIdentify Info:\nID String: %8\nMIME Type: %9\nType: '%10' (%11)\nTranslator ID: %12\nGroup: '%13' (%14)\nQuality: %15\nCapability: %16\n\nExtension Info:\n ImageView Imagem: %1\nEspaço de cor: %2 (%3)\nDimensões: %4 x %5\nBytes por linha: %6\nTotal de Bytes: %7\n\nInformação de Identificação:\nString de identificação: %8\nTipo MIME: %9\nTipo: '%10' (%11)\nID do Tradutor: %12\nGrupo: '%13' (%14)\nQualidade: %15\nCapacidade: %16\n\nInformação de Extensão:\n -\nOutput Formats: ImageView \nFormatos de saída: +\nOutput Formats: ImageView \nFormatos de Saída: Save feature not implemented yet. ImageWindow Recurso salvo ainda não implementado. First Page ImageWindow Primeira Página Next Page ImageWindow Próxima página @@ -23,10 +23,10 @@ OK ImageWindow OK Window ImageWindow Janela Quit ImageWindow Sair Selected Document: %1\n\nTranslator Used:\nName: %2\nInfo: %3\nVersion: %4\n ImageView Documento selecionado: %1\n\nTradutor usado:\nNome: %2\nInformações: %3\nVersão: %4\n -Active Translators ImageWindow Tradutores ativos +Active Translators ImageWindow Tradutores Ativos View ImageWindow Visualizar -Previous Page ImageWindow Página anterior +Previous Page ImageWindow Página Anterior OK ImageView OK -System Translators ActiveTranslatorsWindow Tradutores do sistema +System Translators ActiveTranslatorsWindow Tradutores do Sistema Unknown ImageView Desconhecido File ImageWindow Arquivo diff --git a/data/develop/Jamfile-engine b/data/develop/Jamfile-engine index bdec959add..86c6c3f9a6 100644 --- a/data/develop/Jamfile-engine +++ b/data/develop/Jamfile-engine @@ -329,7 +329,7 @@ if ( $(OSPLAT) = X86 ) switch $(TYPE) { case APP : LINKFLAGS += -Xlinker -soname=_APP_ ; - case SHARED : LINKFLAGS += -nostart -Xlinker -soname=$(NAME) ; + case SHARED : LINKFLAGS += -shared -Xlinker -soname=$(NAME) ; case DRIVER : LINKFLAGS += -nostdlib /boot/develop/lib/x86/_KERNEL_ ; } } diff --git a/data/develop/makefile-engine b/data/develop/makefile-engine index 274b0724a7..cf19c7b900 100644 --- a/data/develop/makefile-engine +++ b/data/develop/makefile-engine @@ -93,7 +93,7 @@ endif LDFLAGS += -Xlinker -soname=_APP_ else ifeq ($(strip $(TYPE)), SHARED) - LDFLAGS += -nostart -Xlinker -soname=$(NAME) + LDFLAGS += -shared -Xlinker -soname=$(NAME) else ifeq ($(strip $(TYPE)), DRIVER) LDFLAGS += -nostdlib /boot/develop/lib/x86/_KERNEL_ \ diff --git a/docs/user/interface/Font.dox b/docs/user/interface/Font.dox index ebf1ca6d7f..6bbbc7ea6c 100644 --- a/docs/user/interface/Font.dox +++ b/docs/user/interface/Font.dox @@ -506,7 +506,8 @@ \struct escapement_delta \ingroup interface \ingroup libbe - \brief The amount of horizontal space surrounding a character. + \brief A struct that allows you to specify extra horizontal space to surround + each character with. Escapements need to be multiplied by the font size to get the correct value for the font. @@ -518,15 +519,15 @@ /*! \var escapement_delta::nonspace - The amount of space surrounding a character with a visible glyph. + The amount of horizontal space to surround a visible glyph character with. */ /*! \var escapement_delta::space - The amount of space surrounding a whitespace character, for example - \c B_TAB and \c B_SPACE. + The amount of horizontal space to surround a whitespace character with, for + example \c B_TAB or \c B_SPACE. */ @@ -1253,14 +1254,14 @@ \fn void BFont::GetEscapements(const char charArray[], int32 numChars, escapement_delta *delta, float escapementArray[]) const \brief Determines the escapements for each char in \a charArray and writes - the result in \a escapementArray with consideration to the provided - escapement \a delta. + the result in \a escapementArray with consideration to the horizontal + space provided by the escapement \a delta. The escapement_delta structure contains the following values: - - \c nonspace The amount of space surrounding a character with a visible - glyph. - - \c space The amount of space surrounding a whitespace character, for - example \c B_TAB and \c B_SPACE. + - \c nonspace The amount of horizontal space to surround a visible glyph + character with. + - \c space The amount of horizontal space to surround a whitespace character + with, for example \c B_TAB or \c B_SPACE. \param charArray The source character array. \param numChars The number of characters to consider in \a charArray. @@ -1274,13 +1275,14 @@ escapement_delta *delta, BPoint escapementArray[]) const \brief Determines the escapements for each char in \a charArray and writes the result in \a escapementArray as an array of BPoint objects - with consideration to the provided escapement \a delta. + with consideration to the horizontal space provided by the escapement + \a delta. The escapement_delta structure contains the following values: - - \c nonspace The amount of space surrounding a character with a visible - glyph. - - \c space The amount of space surrounding a whitespace character, for - example \c B_TAB and \c B_SPACE. + - \c nonspace The amount of horizontal space to surround a visible glyph + character with. + - \c space The amount of horizontal space to surround a whitespace character + with, for example \c B_TAB or \c B_SPACE. \param charArray The source character array. \param numChars The number of characters to consider in \a charArray. @@ -1296,14 +1298,14 @@ BPoint offsetArray[]) const \brief Determines the escapements for each char in \a charArray and writes the result in \a escapementArray as an array of BPoint objects - with consideration to the provided escapement \a delta - and writes offsets to \a offsetArray. + with consideration to the horizontal space provided by the escapement + \a delta and writes the offsets to \a offsetArray. The escapement_delta structure contains the following values: - - \c nonspace The amount of space surrounding a character with a visible - glyph. - - \c space The amount of space surrounding a whitespace character, for - example \c B_TAB and \c B_SPACE. + - \c nonspace The amount of horizontal space to surround a visible glyph + character with. + - \c space The amount of horizontal space to surround a whitespace character + with, for example \c B_TAB or \c B_SPACE. \param charArray The source character array. \param numChars The number of characters to consider in \a charArray. @@ -1370,9 +1372,9 @@ \fn void BFont::GetBoundingBoxesAsString(const char charArray[], int32 numChars, font_metric_mode mode, escapement_delta *delta, BRect boundingBoxArray[]) const - \brief Writes an array of BRect objects to \a boundingBoxArray - representing the bounding rectangles of each character in - \a charArray with consideration to the provided escapement + \brief Writes an array of BRect objects to \a boundingBoxArray representing + the bounding rectangles of each character in \a charArray with + consideration to the horizontal space provided by the escapement \a delta. Each BRect object corresponds to the glyph of one character. @@ -1381,15 +1383,15 @@ - \c B_SCREEN_METRIC The bounding boxes should use the screen metric. - \c B_PRINTING_METRIC The bounding boxes should use the print metric. - Escapement deltas are applied as part of the bounding box calculations. - This lets you specify a character spacing is looser or tighter than - normal. + The provided escapement \a delta is applied as part of the bounding box + calculations. This lets you specify a character spacing is looser or + tighter than normal. The escapement_delta structure contains the following values: - - \c nonspace The amount of space surrounding a character with a visible - glyph. - - \c space The amount of space surrounding a whitespace character, for - example \c B_TAB and \c B_SPACE. + - \c nonspace The amount of horizontal space to surround a visible glyph + character with. + - \c space The amount of horizontal space to surround a whitespace character + with, for example \c B_TAB or \c B_SPACE. \param charArray The source character array. \param numChars The number of characters to consider in \a charArray. @@ -1403,10 +1405,10 @@ \fn void BFont::GetBoundingBoxesForStrings(const char *stringArray[], int32 numStrings, font_metric_mode mode, escapement_delta deltas[], BRect boundingBoxArray[]) const - \brief Writes an array of BRect objects to \a boundingBoxArray - representing the bounding rectangles of each string in - \a stringArray with consideration to the provided escapement - \a delta. + \brief Writes an array of BRect objects to \a boundingBoxArray representing + the bounding rectangles of each string in \a stringArray with + consideration to the horizontal space provided by the escapement + \a deltas. Each BRect object corresponds to the bounding box of the entire string. @@ -1414,15 +1416,15 @@ - \c B_SCREEN_METRIC The bounding boxes should use the screen metric. - \c B_PRINTING_METRIC The bounding boxes should use the print metric. - Escapement deltas are applied as part of the bounding box calculations. - This lets you specify a character spacing is looser or tighter than - normal. + The provided escapement \a deltas are applied as part of the bounding box + calculations. This lets you specify a character spacing is looser or tighter + than normal. - The escapement_delta structures should contain the following values: - - \c nonspace The amount of space surrounding a character with a visible - glyph. - - \c space The amount of space surrounding a whitespace character, for - example \c B_TAB and \c B_SPACE. + The escapement_delta structure contains the following values: + - \c nonspace The amount of horizontal space to surround a visible glyph + character with. + - \c space The amount of horizontal space to surround a whitespace character + with, for example \c B_TAB or \c B_SPACE. \param stringArray The source string array. \param numStrings The number of strings to consider in \a stringArray. diff --git a/docs/user/interface/GraphicsDefs.dox b/docs/user/interface/GraphicsDefs.dox new file mode 100644 index 0000000000..b169423d44 --- /dev/null +++ b/docs/user/interface/GraphicsDefs.dox @@ -0,0 +1,93 @@ +/* + * Copyright 2013 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * John Scipione, jscipione@gmail.com + * + * Corresponds to: + * headers/os/interface/GraphicsDefs.h hrev45737 + * src/kits/interface/GraphicsDefs.cpp hrev45737 + */ + + +/*! + \file GraphicsDefs.h + \ingroup interface + \ingroup libbe + \brief Graphics-related functions and variables used by the Interface Kit. +*/ + + +/*! + \struct pattern + \ingroup interface + \ingroup libbe + \brief A pattern to use when drawing. +*/ + + +/*! + \var B_SOLID_HIGH + + Draw using the view's high color. +*/ + + +/*! + \var B_MIXED_COLORS + + Draw a pattern of the view's high and low colors. +*/ + + +/*! + \var B_SOLID_LOW + + Draw using the view's low color. +*/ + + +/*! + \enum source_alpha + \ingroup interface + + Blending alpha mode constants. +*/ + + +/*! + \var source_alpha B_PIXEL_ALPHA + + Use the alpha value of each pixel when drawing a bitmap. +*/ + + +/*! + \var source_alpha B_CONSTANT_ALPHA + + Use the alpha channel of the view's high color. +*/ + + +/*! + \enum alpha_function + \ingroup interface + + Blending alpha function constants. +*/ + + +/*! + \var alpha_function B_ALPHA_OVERLAY + + Used for drawing a image with transparency over an opaque background. +*/ + + +/*! + \var alpha_function B_ALPHA_COMPOSITE + + Used to composite two or more transparent images together offscreen to + produce a new image drawn using \c B_ALPHA_OVERLAY mode. +*/ diff --git a/docs/user/interface/InterfaceDefs.dox b/docs/user/interface/InterfaceDefs.dox index 089203ff9f..99f9d456f8 100644 --- a/docs/user/interface/InterfaceDefs.dox +++ b/docs/user/interface/InterfaceDefs.dox @@ -1,13 +1,13 @@ /* - * Copyright 2011 Haiku, Inc. All rights reserved. + * Copyright 2011-2013 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * John Scipione, jscipione@gmail.com * * Corresponds to: - * headers/os/interface/InterfaceDefs.h rev 43230 - * src/kits/interface/InterfaceDefs.cpp rev 43230 + * headers/os/interface/InterfaceDefs.h hrev45737 + * src/kits/interface/InterfaceDefs.cpp hrev45737 */ @@ -107,6 +107,85 @@ */ +// Line join and cap modes + + +/*! + \enum join_mode + + PostScript-style line join modes used by BView::SetLineMode() +*/ + + +/*! + \var join_mode B_ROUND_JOIN + + Round join mode. +*/ + + +/*! + \var join_mode B_MITER_JOIN + + Miter join mode. +*/ + + +/*! + \var join_mode B_BEVEL_JOIN + + Bevel join mode. +*/ + + +/*! + \var join_mode B_BUTT_JOIN + + Butt join mode. +*/ + +/*! + \var join_mode B_SQUARE_JOIN + + Square join mode. +*/ + + +/*! + \enum cap_mode + + PostScript-style line cap modes used by BView::SetLineMode() +*/ + + +/*! + \var cap_mode B_ROUND_CAP + + Round cap mode. +*/ + + +/*! + \var cap_mode B_BUTT_CAP + + Butt cap mode. +*/ + + +/*! + \var cap_mode B_SQUARE_CAP + + Square cap mode. +*/ + + +/*! + \var B_DEFAULT_MITER_LIMIT + + Default miter limit used to calculate the angle cut off for miter joins. +*/ + + ///// Keyboard related functions diff --git a/docs/user/interface/View.dox b/docs/user/interface/View.dox index c213b5fd94..d227f64e24 100644 --- a/docs/user/interface/View.dox +++ b/docs/user/interface/View.dox @@ -1,13 +1,13 @@ /* - * Copyright 2011 Haiku, Inc. All rights reserved. + * Copyright 2011-2013 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * John Scipione, jscipione@gmail.com * * Corresponds to: - * headers/os/interface/View.h rev 42794 - * src/kits/interface/View.cpp rev 42794 + * headers/os/interface/View.h hrev45799 + * src/kits/interface/View.cpp hrev45799 */ @@ -19,11 +19,700 @@ */ +// mouse buttons + + +/*! + \var B_PRIMARY_MOUSE_BUTTON + + Primary mouse button mask parameter. +*/ + + +/*! + \var B_SECONDARY_MOUSE_BUTTON + + Secondary mouse button mask parameter. +*/ + + +/*! + \var B_TERTIARY_MOUSE_BUTTON + + Tertiary mouse button mask parameter. +*/ + + +// mouse transit + + +/*! + \var B_ENTERED_VIEW + + Mouse transit entered view. +*/ + + +/*! + \var B_INSIDE_VIEW + + Mouse transit inside view. +*/ + + +/*! + \var B_EXITED_VIEW + + Mouse transit exited view. +*/ + + +/*! + \var B_OUTSIDE_VIEW + + Mouse transit outside view. +*/ + + +// event mask + + +/*! + \var B_POINTER_EVENTS + + Mouse pointer events mask parameter. +*/ + + +/*! + \var B_KEYBOARD_EVENTS + + Keyboard events mask parameter. +*/ + + +// event mask options + + +/*! + \var B_LOCK_WINDOW_FOCUS + + Prevents the attached window from losing its focused state while the mouse is + held down. +*/ + + +/*! + \var B_SUSPEND_VIEW_FOCUS + + Events normally sent to the focus view are suppressed. +*/ + + +/*! + \var B_NO_POINTER_HISTORY + + Send only the most recent MouseMoved() event to the view. + + \note New in Haiku: unless this flag is specified, both BWindow and + BView::GetMouse() will filter out older mouse moved messages. +*/ + + +/*! + \var B_FULL_POINTER_HISTORY + + Send all MouseMoved() events to the view. +*/ + + +// event tracking + + +/*! + \var B_TRACK_WHOLE_RECT + + The whole rectangle moves with the cursor. +*/ + + +/*! + \var B_TRACK_RECT_CORNER + + The left top corner is fixed while the right and bottom edges move with the + cursor. +*/ + + +// set font mask + + +/*! + \var B_FONT_FAMILY_AND_STYLE + + Font family and style mask parameter. +*/ + + +/*! + \var B_FONT_SIZE + + Font size mask parameter. +*/ + + +/*! + \var B_FONT_SHEAR + + Font shear mask parameter. +*/ + + +/*! + \var B_FONT_ROTATION + + Font rotation mask parameter. +*/ + + +/*! + \var B_FONT_SPACING + + Font spacing mask parameter. +*/ + + +/*! + \var B_FONT_ENCODING + + Font encoding mask parameter. +*/ + + +/*! + \var B_FONT_FACE + + Font face mask parameter. +*/ + + +/*! + \var B_FONT_FLAGS + + Font flags mask parameter. +*/ + + +/*! + \var B_FONT_FALSE_BOLD_WIDTH + + Font false bold width mask parameter. +*/ + + +/*! + \var B_FONT_ALL + + Font all properties mask parameter. +*/ + + +// view flags + + +/*! + \var B_FULL_UPDATE_ON_RESIZE + + Redraw the entire view on resize. +*/ + + +/*! + \var _B_RESERVED1_ + + Reserved for future use. +*/ + + +/*! + \var B_WILL_DRAW + + Indicates that the view will do it's own drawing. +*/ + + +/*! + \var B_PULSE_NEEDED + + Indicates that the view accepts Pulse() messages. +*/ + + +/*! + \var B_NAVIGABLE_JUMP + + Indicates this is the default keyboard navigation view. +*/ + +/*! + \var B_FRAME_EVENTS + + View responds to frame move and resize events. +*/ + + +/*! + \var B_NAVIGABLE + + The view is able to receive focus for keyboard navigation. Typically focus is + indicated by drawing a blue rectangle around the view. +*/ + + +/*! + \var B_SUBPIXEL_PRECISE + + The view draws with sub-pixel precision. +*/ + + +/*! + \var B_DRAW_ON_CHILDREN + + Indicates that the view responds to the DrawAfterChildren() hook method. +*/ + + +/*! + \var B_INPUT_METHOD_AWARE + + Allows the view to use input method add-ons to gain access to the input + methods needed for Japanese and other languages. +*/ + + +/*! + \var _B_RESERVED7_ + + Reserved for future use. +*/ + + +/*! + \var B_SUPPORTS_LAYOUT + + The view supports the layout APIs, i.e. it doesn't require an explicit frame + rectangle to be specified. +*/ + + +/*! + \var B_INVALIDATE_AFTER_LAYOUT + + Indicates that the view should be redraw after being added to a layout. +*/ + + +// resize mask variables, internal variables but are in a public header. + + +/*! + \var _RESIZE_MASK_ + + Resize mask. Do not use. +*/ + + +/*! + \var _VIEW_TOP_ + + View top mask variable. Do not use. +*/ + + +/*! + \var _VIEW_LEFT_ + + View left mask variable. Do not use. +*/ + + +/*! + \var _VIEW_BOTTOM_ + + View bottom mask variable. Do not use. +*/ + + +/*! + \var _VIEW_RIGHT_ + + View right mask variable. Do not use. +*/ + + +/*! + \var _VIEW_CENTER_ + + View center mask variable. Do not use. +*/ + + +/*! + \fn inline uint32 _rule_(uint32 r1, uint32 r2, uint32 r3, uint32 r4) + \brief Internal function, do not use. +*/ + + +// resize mask + + +/*! + \var B_FOLLOW_NONE + + Follow none resize mask parameter. Equivalent to \c B_FOLLOW_LEFT + | \c B_FOLLOW_TOP. The view maintains its position in its parent's + coordinate system but not in the screen coordinate system. +*/ + + +/*! + \var B_FOLLOW_ALL_SIDES + + Follow all sides resize mask parameter. Equivalent to \c B_FOLLOW_LEFT_RIGHT | + \c B_FOLLOW_TOP_BOTTOM. The view will be resized with its parent view both + horizontally and vertically. +*/ + + +/*! + \var B_FOLLOW_ALL + + Equivalent to \c B_FOLLOW_ALL_SIDES. +*/ + + +// horizontal resize mask + + +/*! + \var B_FOLLOW_LEFT + + The margin between the left side of the view and the left side of its parent + remains constant. +*/ + + +/*! + \var B_FOLLOW_RIGHT + + The margin between the right side of the view and the right side of its parent + remains constant. +*/ + + +/*! + \var B_FOLLOW_LEFT_RIGHT + + The margin between the left and right sides of the view and the left and right + sides of its parent both remain constant. +*/ + + +/*! + \var B_FOLLOW_H_CENTER + + The view maintains a constant relationship to the horizontal center of its + parent view. +*/ + + +// vertical resize mask + + +/*! + \var B_FOLLOW_TOP + + The margin between the top of the view and the top of its parent remains + constant. +*/ + + +/*! + \var B_FOLLOW_BOTTOM + + The margin between the bottom of the view and the bottom of its parent remains + constant. +*/ + + +/*! + \var B_FOLLOW_TOP_BOTTOM + + The margin between the top and bottom sides of the view and the top and bottom + sides of its parent both remain constant. +*/ + + +/*! + \var B_FOLLOW_V_CENTER + + The view maintains a constant relationship to the vertical center of its + parent view. +*/ + + /*! \class BView \ingroup interface \ingroup libbe \brief View base class. + + A BView is a rectangular area within a window that responds to mouse clicks + and key presses, and acts as a surface for you to draw on. + + Most Interface Kit classes, with the notable exception of BWindow inherit from + BView. Some of the time you might use a BView object as is, but most of the + time you subclass BView to do something unique. + + To create a subclass of BView you generally override one or more of BView's + hook methods to respond to user events such as MouseDown() or FrameMoved(). + By default a BView does nothing in it's hook methods unless otherwise stated, + it's up to you to define what happens. To override the look of a BView you + should override the Draw() or DrawAfterChildren() methods. See the section on + Hook Methods below for more details. + + When a BView object is first created it has no parent or child views. How you + add a view to the view hierarchy depends on if you want to use a standard + view with a defined frame rectangle or to use the Layout APIs to position and + size your view instead. + + If you create a standard view you need to add it to a window or another view + using the AddChild() method, if you create a layout view you need to add your + view to a layout using BLayout::AddView() or by adding it to a layout builder. + + Views are not very interesting until they, or one of their parents, are + attached to a window as many of BView's methods depend on a connection to the + App Server to do their work. In order to prevent multiple views from altering + the window simultaneously though locking is required. To perform an action + while the window is locked you issue the following code: + +\code +if (Window()->LockLooper()) { + ... + Window()->UnlockLooper() +} +\endcode + + Whenever App Server calls a hook method it automatically locks the BWindow for + you. + + Only one view attached to a window is able to receive keyboard events at a + time. The view that is able to receive keyboard events such as KeyDown() is + called the "focus view". MakeFocus() gives or removes focus from a view. + Call IsFocus() to determine whether or not the view is the window's current + focus view. + + When a view has focus an indicator should be drawn to inform the user. Typically + the view is surrounded by a blue rectangle to indicate that it is the window's + focus view. The color can be queried using the keyboard_navigation_color() + function in InterfaceDefs.h + + Each view has it's own coordinate system with the origin point (0.0, 0.0) + located at the top left corner. You can convert a BPoint or BRect to or from + the view's coordinate system to the coordinate system of it's parent, or + of the screen's coordinate system. See the section on Coordinate Conversion + Methods for more details. + + The Application Server clips a BView to the region where it's permitted to + draw which is never larger than the view's bound rectangle. A view can never + draw outside its bounds nor can it draw outside of the bounds rectangle of any + parent view. + + You may limit the clipping region further by passing a BRegion object to + ConstrainClippingRegion(). You can obtain the current clipping region by + calling GetClippingRegion(). + + Each view has a ViewColor() that fills the frame rectangle before the + view does any drawing of its own. The default view color is white, you may + change the view color by calling SetViewColor(). A commonly used view color + is \c B_PANEL_BACKGROUND_COLOR which is a grey color used as the view color + of many Interface Kit classes. If you set the view color to + \c B_TRANSPARENT_COLOR then the Application Server won't erase the clipping + region of the view before updating, this should only be used if the view + erases itself by drawing on every pixel in the clipping region. + + If you want to set the view color of a view to be the same as its parent you + need to set it within the AttachedToWindow() method of the view like so: + +\code +SetViewColor(Parent()->ViewColor()); +\endcode +*/ + + +/*! + \fn BView::BView(const char* name, uint32 flags, BLayout* layout) + \brief Layout constructor. + + To be used as part of a BLayout. You may use the Layout Methods found below + to set the size and alignment constraints of the view. + + \c B_SUPPORTS_LAYOUT is automatically set to the view. The view flags can be + set after the view has been constructed by calling the SetFlags() methods. + + \param name The name of the view, can be \c NULL. + \param flags The view flags, a mask of one or more of the following: + - \c B_FULL_UPDATE_ON_RESIZE Redraw the entire view on resize. + - \c B_WILL_DRAW Indicates that the view will do it's own drawing. + - \c B_PULSE_NEEDED The view accepts Pulse() messages. + - \c B_NAVIGABLE_JUMP Default for keyboard navigation. + - \c B_FRAME_EVENTS Responds to move and resize events. + - \c B_NAVIGABLE Able to receive keyboard navigation focus. + - \c B_SUBPIXEL_PRECISE Draws with sub-pixel precision. + - \c B_DRAW_ON_CHILDREN Responds to DrawAfterChildren(). + - \c B_INPUT_METHOD_AWARE Allows access input method add-ons. + - \c B_SUPPORTS_LAYOUT Supports the layout APIs, i.e. it doesn't + use a frame rectangle. + - \c B_INVALIDATE_AFTER_LAYOUT Is redraw after added to a layout. + \param layout A \a layout to set the view to. +*/ + + +/*! + \fn BView::BView(BRect frame, const char* name, uint32 resizingMode, + uint32 flags) + \brief Standard constructor. + + A newly constructed BView object has no parent, you must assign it one by + passing it into the AddChild() method of another view or window. Once the + view or a parent view has been attached to a window the view becomes part of + that window's view hierarchy. + + When the BView object is added as a child the \a frame values are interpreted + in the parent's coordinate system. The frame rectangle should be specified in + integral values to align on pixel boundaries, decimal values will be rounded. + + The resizing mode flags and view flags can be set after the view has been + constructed by calling the SetResizingMode() and SetFlags() methods. + + \param frame The \a frame rectangle of the view. + \param name The name of the view, can be \c NULL. + \param resizingMode Defines the view's behavior of the when its parent is + resized. + \n\n It combines one of the following horizontal resizing constants: + \li \c B_FOLLOW_TOP The margin between the top of the view and the top + of its parent remains constant. + \li \c B_FOLLOW_BOTTOM The margin between the bottom of the view and + the bottom of its parent remains constant. + \li \c B_FOLLOW_TOP_BOTTOM The margin between the top and bottom sides + of the view and the top and bottom sides of the parent both remain + constant. + \li \c B_FOLLOW_V_CENTER Maintains a constant relationship to the + vertical center of the parent view. + + with one of the following vertical resizing constants: + \li \c B_FOLLOW_LEFT The margin between the left side of the view and + the left side of its parent remains constant. + \li \c B_FOLLOW_RIGHT The margin between the right side of the view and + the right side of the parent remains constant. + \li \c B_FOLLOW_LEFT_RIGHT The margin between the left and right sides + of the view and the left and right sides of its parent both remain + constant. + \li \c B_FOLLOW_H_CENTER The view maintains a constant relationship to + the horizontal center of the parent view. + + or use one of the following combined horizontal/vertical constants: + \li \c B_FOLLOW_NONE Equivalent to \c B_FOLLOW_LEFT | \c B_FOLLOW_TOP. + \li \c B_FOLLOW_ALL_SIDES Equivalent to + \c B_FOLLOW_LEFT_RIGHT | \c B_FOLLOW_TOP_BOTTOM. + \param flags The view flags, a mask of one or more of the following: + - \c B_FULL_UPDATE_ON_RESIZE Redraw the entire view on resize. + - \c B_WILL_DRAW Indicates that the view will do it's own drawing. + - \c B_PULSE_NEEDED The view accepts Pulse() messages. + - \c B_NAVIGABLE_JUMP Default for keyboard navigation. + - \c B_FRAME_EVENTS Responds to move and resize events. + - \c B_NAVIGABLE Able to receive keyboard navigation focus. + - \c B_SUBPIXEL_PRECISE Draws with sub-pixel precision. + - \c B_DRAW_ON_CHILDREN Responds to DrawAfterChildren(). + - \c B_INPUT_METHOD_AWARE Allows access input method add-ons. + - \c B_SUPPORTS_LAYOUT Supports the layout APIs, i.e. it doesn't + use a frame rectangle. + - \c B_INVALIDATE_AFTER_LAYOUT Is redraw after added to a layout. +*/ + + +/*! + \fn BView::BView(BMessage* archive) + \brief Archive constructor. + + \param archive The data \a archive message to construct the view from. +*/ + + +/*! + \fn BView::~BView() + \brief Destructor method. + + Deletes the view and all children freeing any memory used. +*/ + + +/*! + \name Archiving +*/ + + +//! @{ + + +/*! + \fn BArchivable* BView::Instantiate(BMessage* data) + \brief Creates a new BView object from the \a data message. + + \returns A newly created BView object or \c NULL if the message doesn't + contain an archived BView object. +*/ + + +/*! + \fn status_t BView::Archive(BMessage* data, bool deep) const + \brief Archives the object into the \a data message. + + \param data A pointer to the BMessage object to archive the object into. + \param deep Whether or not to archive child views as well. + + \return A status code, \c B_OK if everything went well or an error code + otherwise. + \retval B_OK The object was archived successfully. + \retval B_NO_MEMORY Ran out of memory while archiving the object. +*/ + + +//! @} + + +/*! + \name Hook Methods +*/ + + +//! @{ + + +/*! + \fn status_t BView::AllUnarchived(const BMessage* from) + \brief Hook method called when all views have been unarchived. + + The default implementation does nothing. +*/ + + +/*! + \fn status_t BView::AllArchived(BMessage* into) const + \brief Hook method called when all views have been archived. + + The default implementation does nothing. */ @@ -31,6 +720,8 @@ \fn void BView::AttachedToWindow() \brief Hook method that is called when the object is attached to a window. + + The default implementation does nothing. */ @@ -38,6 +729,8 @@ \fn void BView::AllAttached() \brief Similar to AttachedToWindow() but this method is triggered after all child views have already been attached to a window. + + The default implementation does nothing. */ @@ -45,25 +738,33 @@ \fn void BView::DetachedFromWindow() \brief Hook method that is called when the object is detached from a window. + + The default implementation does nothing. */ + /*! \fn void BView::AllDetached() \brief Similar to AttachedToWindow() but this method is triggered after all child views have already been detached from a window. + + The default implementation does nothing. */ + /*! \fn void BView::Draw(BRect updateRect) \brief Draws the area of the view that intersects \a updateRect. Derived classes should override this method to draw their view. - \note This is an hook method called by the Interface Kit, you don't - have to call it yourself. If you need to forcefully redraw the view - consider calling Invalidate() instead. + \remark This is an hook method called by the Interface Kit, you don't have to + call it yourself. If you need to forcefully redraw the view consider + calling Invalidate() instead. \param updateRect The rectangular area to be drawn. + + The default implementation does nothing. */ @@ -73,6 +774,8 @@ already been drawn. \param r The rectangular area to be drawn. + + The default implementation does nothing. */ @@ -82,6 +785,8 @@ \param newPosition The point of the top left corner of the frame that the view has been moved to. + + The default implementation does nothing. */ @@ -91,6 +796,477 @@ \param newWidth The new \a width of the view. \param newHeight The new \a height of the view. + + The default implementation does nothing. +*/ + + +/*! + \fn void BView::KeyDown(const char* bytes, int32 numBytes) + \brief Hook method that is called when a keyboard key is pressed. + + \param bytes The bytes of the key combination pressed. + \param numBytes The number of bytes in \a bytes. + + The default implementation sets keyboard navigation focus. +*/ + + +/*! + \fn void BView::KeyUp(const char* bytes, int32 numBytes) + \brief Hook method that is called when a keyboard key is released. + + \param bytes The bytes of the key combination pressed. + \param numBytes The number of bytes in \a bytes. + + The default implementation does nothing. +*/ + + +/*! + \fn void BView::LayoutInvalidated(bool descendants) + \brief Hook method that is called when the layout is invalidated. + + \note This method was not available in BeOS R5. + + \param descendants Whether or not child views have also been invalidated. + + The default implementation does nothing. +*/ + + +/*! + \fn void BView::MessageReceived(BMessage* message) + \brief Handle \a message received by the associated looper. + + \param message The \a message received by the associated looper. + + \see BHandler::MessageReceived() +*/ + + +/*! + \fn void BView::MouseDown(BPoint where) + \brief Hook method that is called when a mouse button is pressed. + + \param where The point on the screen where to mouse pointer is when + the mouse button is pressed. + + The default implementation does nothing. +*/ + + +/*! + \fn void BView::MouseUp(BPoint where) + \brief Hook method that is called when a mouse button is released. + + \param where The point on the screen where to mouse pointer is when + the mouse button is released. + + The default implementation does nothing. +*/ + + +/*! + \fn void BView::MouseMoved(BPoint where, uint32 code, + const BMessage* a_message) + \brief Hook method that is called when the mouse is moved. + + The default implementation does nothing. +*/ + + +/*! + \fn void BView::Pulse() + \brief Hook method that gets called when the view receives a \c B_PULSE + message. + + An action is performed each time the App Server calls the Pulse() method. + The pulse rate is set by SetPulseRate(). You can implement Pulse() to do + anything you want. The default version does nothing. The pulse granularity + is no better than once per 100,000 microseconds. + + The default implementation does nothing. + + \sa SetPulseRate() +*/ + + +/*! + \fn void BView::TargetedByScrollView(BScrollView* scrollView) + \brief Hook method called when the view becomes the target of + \a scrollView. + + The default implementation does nothing. + + \param scrollView The BScrollView object that has targeted the view. +*/ + + +/*! + \fn void BView::WindowActivated(bool state) + \brief Hook method called when the attached window becomes activated or + deactivated. + + The default implementation does nothing. + + \param state \c true if the window becomes activated, \c false if the + window becomes deactivated. +*/ + + +//! @} + + +/*! + \fn BRect BView::Bounds() const + \brief Returns the view frame rectangle in the view's coordinate system. + + \return The bounding rectangle of the view. +*/ + + +/*! + \fn BRect BView::Frame() const + \brief Returns the frame rectangle of the view in the parent's coordinate system. + + \returns The view's frame rectangle. +*/ + + +/*! + \name Coordinate Conversion Methods +*/ + + +//! @{ + + +/*! + \fn void BView::ConvertToParent(BPoint* point) const + \brief Convert \a point to the parent's coordinate system in place. + + \param point A pointer to a BPoint object to convert. +*/ + + +/*! + \fn BPoint BView::ConvertToParent(BPoint point) const + \brief Returns \a point converted to the parent's coordinate system. + + \param point A BPoint object to convert. + + \return A new BPoint object in the parent's coordinate system. +*/ + + +/*! + \fn void BView::ConvertFromParent(BPoint* point) const + \brief Convert \a point from the parent's coordinate system to the + view's coordinate system in place. + + \param point A pointer to a BPoint object to convert. +*/ + + +/*! + \fn BPoint BView::ConvertFromParent(BPoint point) const + \brief Returns \a point converted from the parent's coordinate system to + the view's coordinate system. + + \param point A BPoint object to convert. + + \return A new BPoint object in the view's coordinate system. +*/ + + +/*! + \fn void BView::ConvertToParent(BRect* rect) const + \brief Convert \a rect to the parent's coordinate system in place. + + \param rect A pointer to a BRect object to convert. +*/ + + +/*! + \fn BRect BView::ConvertToParent(BRect rect) const + \brief Returns \a rect converted to the parent's coordinate system. + + \param rect A BRect object to convert. + + \return A new BRect object in the parent's coordinate system. +*/ + + +/*! + \fn void BView::ConvertFromParent(BRect* rect) const + \brief Convert \a rect from the parent's coordinate system to the + view's coordinate system in place. + + \param rect A pointer to a BRect object to convert. +*/ + + +/*! + \fn BRect BView::ConvertFromParent(BRect rect) const + \brief Returns \a rect converted from the parent's coordinate system to the + view's coordinate system. + + \param rect A BRect object to convert. + + \return A new BRect object in the view's coordinate system. +*/ + + +/*! + \fn void BView::ConvertToScreen(BPoint* point) const + \brief Convert \a point to the screen's coordinate system in place. + + \param point A pointer to a BPoint object to convert. +*/ + + +/*! + \fn BPoint BView::ConvertToScreen(BPoint point) const + \brief Returns \a point converted to the screen's coordinate system. + + \param point A BPoint object to convert. + + \return A new BPoint object in the screen's coordinate system. +*/ + + +/*! + \fn void BView::ConvertFromScreen(BPoint* point) const + \brief Convert \a point from the screen's coordinate system to the + view's coordinate system in place. + + \param point A pointer to a BPoint object to convert. +*/ + + +/*! + \fn BPoint BView::ConvertFromScreen(BPoint point) const + \brief Returns \a point converted from the screen's coordinate system to + the view's coordinate system. + + \param point A BPoint object to convert. + + \return A new BPoint object in the view's coordinate system. +*/ + + +/*! + \fn void BView::ConvertToScreen(BRect* rect) const + \brief Convert \a rect to the screen's coordinate system in place. + + \param rect A pointer to a BRect object to convert. +*/ + + +/*! + \fn BRect BView::ConvertToScreen(BRect rect) const + \brief Returns \a rect converted to the screen's coordinate system. + + \param rect A BRect object to convert. + + \return A new BRect object in the screen's coordinate system. +*/ + + +/*! + \fn void BView::ConvertFromScreen(BRect* rect) const + \brief Convert \a rect from the screen's coordinate system to the + view's coordinate system in place. + + \param rect A pointer to a BRect object to convert. +*/ + + +/*! + \fn BRect BView::ConvertFromScreen(BRect rect) const + \brief Returns \a rect converted from the screen's coordinate system to the + view's coordinate system. + + \param rect A BRect object to convert. + + \return A new BRect object in the view's coordinate system. +*/ + + +//! @} + + +/*! + \fn uint32 BView::Flags() const + \brief Return the view flags set in the constructor or by SetFlags(). + + \return The view flags as a uint32 mask. +*/ + + +/*! + \fn void BView::SetFlags(uint32 flags) + \brief Sets the view flags to the \a flags mask. + + \param flags The view flags to set as a uint32 mask. +*/ + + +//! @} + + +/*! + \fn void BView::Hide() + \brief Hides the view without removing it from the view hierarchy. + + Calls to Hide() and Show() are cumulative. A visible view becomes hidden + once the number of Hide() calls exceeds the number of Show() calls. + + \see BWindow::Hide() + \see IsHidden() +*/ + + +/*! + \fn void BView::Show() + \brief Shows the view making it visible. + + Calls to Hide() and Show() are cumulative. A hidden view becomes visible + again once the number of Show() calls matches the number of Hide() calls. + + \see BWindow::Show() + \see IsHidden() +*/ + + +/*! + \fn bool BView::IsFocus() const + \brief Returns whether or not the view is the window's current focus view. + + The focus view changes as the user moves from one view to another either + by pushing the tab key or by clicking a new view with the mouse. The change + can be made programmatically via the MakeFocus() method. + + \returns \c true if the view is the current focus view, \c false otherwise. + + \see MakeFocus() + \see BWindow::CurrentFocus() +*/ + + +/*! + \fn bool BView::IsHidden(const BView* lookingFrom) const + \brief Returns whether or not the view is hidden from the perspective of + \a lookingFrom. + + A view is considered hidden if it, any of it's parent views, or the window + it is attached to has had the Hide() method called on it. This method + allows you to determine the hidden status of a view from a different point + on the view hierarchy. + + \param lookingFrom The view used as a base when determining the hidden + status of the BView object. + + \return \c true if the view was hidden via the Hide() method, \c false + otherwise. +*/ + + +/*! + \fn bool BView::IsHidden() const + \brief Returns whether or not the view is hidden. + + A view can be hidden either by calling Hide() on the view, calling Hide() + on a parent view or calling Hide() on the window that the view is attached + to. When a BWindow or BView is hidden, all its descendants are also hidden. + + This method only returns whether the view or an ancestor view has had the + Hide() method called on it, it doesn't consider if the view is obscured + by another view or is off-screen. A BView is not hidden by default. + + \return \c true if the view was hidden via the Hide() method, \c false + otherwise. +*/ + + +/*! + \fn bool BView::IsPrinting() const + \brief Returns whether or not the BView object is drawing to a printer. + + This method should only be called from the Draw() or DrawAfterChildren() + methods. If called from any other method this method returns \c false. + + The view may choose different fonts, images, or colors when drawing to a + printer vs. when drawing to the screen. + + \return Returns \c true if drawing to a printer, \c false otherwise. +*/ + + +/*! + \fn BPoint BView::LeftTop() const + \brief Returns the left top corner point. + + \return The left top corner of the view as a BPoint object. +*/ + + +/*! + \fn void BView::SetResizingMode(uint32 mode) + \brief Sets the resizing mode of the view according to the \a mode mask. + + The resizing mode is first set in the BView constructor. + + \see SetFlags() +*/ + + +/*! + \fn uint32 BView::ResizingMode() const + \brief Returns the resizing mode flags mask set in the constructor or by + SetResizingMode(). + + \returns the current resizing mode flags as a uint32 mask. +*/ + + +/*! + \fn void BView::SetViewCursor(const BCursor* cursor, bool sync) + \brief Assigns \a cursor to the view. + + This cursor will be displayed when the mouse is positioned inside the view. + + \param cursor The BCursor object to assign to the view. + \param sync If \c true App Server is synchronized immediately forcing the + change to occur. If \c false, the change will be put in the queue and + will take effect when the pending requests are processed. +*/ + + +/*! + \fn void BView::Flush() const + \brief Flushes the attached window's connection to App Server. + + If the view isn't attached to a window, Flush() does nothing. +*/ + + +/*! + \fn void BView::Sync() const + \brief Synchronizes the attached window's connection to App Server. + + \warning If the view isn't attached to a window, Sync() might crash the + application. +*/ + + +/*! + \fn BWindow* BView::Window() const + \brief Returns the window the view is attached to. + + \return The window the view is attached to or \c NULL if the view isn't + attached to a window. */ @@ -102,8 +1278,8 @@ Derived classes should override this method to set the preferred size of object. - \note Either the \a _width or \a _height parameter may be set to \c NULL - if you only want to get the other one. + \remark Either the \a _width or \a _height parameter may be set to \c NULL + if you only want to get the other one. \param[out] _width Pointer to a \c float to store the width of the view. \param[out] _height Pointer to a \c float to store the height of the view. @@ -112,85 +1288,2119 @@ /*! \fn void BView::ResizeToPreferred() - \brief Resize the view to its preferred size. + \brief Resizes the view to its preferred size keeping the left top corner + constant. */ /*! - \fn void BView::KeyDown(const char* bytes, int32 numBytes) - \brief Hook method that is called when a keyboard key is pressed. + \name Input Related Methods +*/ - \param bytes The bytes of the key combination pressed. - \param numBytes The number of bytes in \a bytes. + +//! @{ + + +/*! + \fn void BView::BeginRectTracking(BRect startRect, uint32 style) + \brief Displays an outline rectangle on the view and initiates tracking. + + This method is typically called from the MouseDown() while EndRectTracking() + is typically called from the MouseUp method(). + + \param startRect The initial frame in the view's coordinate system. + \param style This parameter is set to one of the following: + - \c B_TRACK_WHOLE_RECT The position of the rect changes with the cursor + while its size remains the same. + - \c B_TRACK_RECT_CORNER The left top corner is fixed while the right and + bottom edges move with the cursor. */ /*! - \fn void BView::KeyUp(const char* bytes, int32 numBytes) - \brief Hook method that is called when a keyboard key is released. + \fn void BView::EndRectTracking() + \brief Ends tracking removing the outline rectangle from the view. - \param bytes The bytes of the key combination pressed. - \param numBytes The number of bytes in \a bytes. + BeginRectTracking() is typically called from the MouseDown() while this + method is typically called from the MouseUp() method. */ /*! - \fn void BView::MouseDown(BPoint where) - \brief Hook method that is called when a mouse button is pressed. + \fn void BView::DragMessage(BMessage* message, BRect dragRect, + BHandler* replyTo) + \brief Initiates a drag-and-drop session. - \param where The point on the screen where to mouse pointer is when - the mouse button is pressed. + This method only works if the BView objects are attached to a window. + + \param message Contains data to be dragged and dropped on the destination + view. The caller retains responsibility for this object. + \param dragRect An outline rectangle used in place of a bitmap image set in + the view's coordinate system. + \param replyTo The target set to handle the message sent in reply to the + dragged message. If \c NULL the reply is instead directed to the + BView object that initiated the drag-and-drop session. */ /*! - \fn void BView::MouseUp(BPoint where) - \brief Hook method that is called when a mouse button is released. + \fn void BView::DragMessage(BMessage* message, BBitmap* image, + BPoint offset, BHandler* replyTo) + \brief Initiates a drag-and-drop session of an \a image. - \param where The point on the screen where to mouse pointer is when - the mouse button is released. + This method only works if the BView objects are attached to a window. + + \param message Contains data to be dragged and dropped on the destination + view. The caller retains responsibility for this object. + \param image Bitmap image dragged by the user. The memory used by the bitmap + is freed automatically when the message is dropped. + \param offset The offset to the hotspot within the image in the bitmap's + coordinate system. + \param replyTo The target set to handle the message sent in reply to the + dragged message. If \c NULL the reply is instead directed to the + BView object that initiated the drag-and-drop session. */ /*! - \fn void BView::MouseMoved(BPoint where, uint32 code, - const BMessage* a_message) - \brief Hook method that is called when the mouse is moved. + \fn void BView::DragMessage(BMessage* message, BBitmap* image, + drawing_mode dragMode, BPoint offset, BHandler* replyTo) + \brief Initiates a drag-and-drop session of an \a image with drawing_mode + set by \a dragMode. + + This method only works if the BView objects are attached to a window. + + \param message Contains data to be dragged and dropped on the destination + view. The caller retains responsibility for this object. + \param image Bitmap image dragged by the user. The memory used by the bitmap + is freed automatically when the message is dropped. + \param dragMode Sets the drawing_mode used to draw the dragged image. Set to + \c B_OP_ALPHA to drag-and-drop partially transparent images. + \param offset The offset to the hotspot within the image in the bitmap's + coordinate system. + \param replyTo The target set to handle the message sent in reply to the + dragged message. If \c NULL the reply is instead directed to the + BView object that initiated the drag-and-drop session. */ /*! - \fn void BView::Pulse() - \brief Hook method that gets invoked when the view receives a - \c B_PULSE message. + \fn void BView::GetMouse(BPoint* _location, uint32* _buttons, + bool checkMessageQueue) + \brief Fills out the cursor location and the current state of the mouse + buttons. - An action is performed each time the App Server calls the Pulse() method. - The pulse rate is set by SetPulseRate(). You can implement Pulse() to do - anything you want. The default version does nothing. The pulse granularity - is no better than once per 100,000 microseconds. + The cursor doesn't have to be located within the view for this method to work, + however, the view must be attached to a window. Don't use this method to track + the mouse in your derived view, implement MouseMoved() instead. - \sa SetPulseRate() -*/ - - -/*! - \fn void BView::WindowActivated(bool state) - \brief Hook method that is called when the attached window becomes - activated or deactivated. - - \param state \c true if the window becomes activated, \c false if the - window becomes deactivated. + \param[out] _location Filled out with the cursor location in the view's + coordinate system. + \param[out] _buttons Filled out with a mask of the following values: + - \c B_PRIMARY_MOUSE_BUTTON + - \c B_SECONDARY_MOUSE_BUTTON + - \c B_TERTIARY_MOUSE_BUTTON + \param checkMessageQueue If \c true pull from any pending MouseMoved() or + MouseUp() events in the message queue top down before filling out + the current mouse cursor state. */ /*! \fn void BView::MakeFocus(bool focusState) - \brief Gives or removes focus from the control. + \brief Makes the view the current focus view of the window or gives up + being the focus view of the window. + + The focus view handles selections and KeyDown events when the the attached + window is active. There can be only one focus view at a time per window. + + When called with \a focusState set to \c true this method first calls + MakeFocus() on the previously focused view with \a focusState set to + \c false. + + The focus doesn't automatically change when MouseDown is called so calling + MakeFocus() is the only way to make a view the focus view of a window. + Classes derived from BView that can display the current selection, or that + can accept pasted data should call MakeFocus() in their MouseDown() method + to update the focus view of the window on click. + + If the view isn't attached to a window this method has no effect. \param focusState \a true to set focus, \a false to remove it. */ +/*! + \fn BScrollBar* BView::ScrollBar(orientation posture) const + \brief Returns the BScrollBar object that has the BView set as its target. + + \param posture Either \c B_VERTICAL to get the vertical scroll bar or + \c B_HORIZONTAL to get the horizontal scroll bar. + + \returns the Scrollbar object requested or \c NULL if none found. + + \see BScrollBar::SetTarget() +*/ + + +/*! + \fn void BView::ScrollBy(float deltaX, float deltaY) + \brief Scroll the view by \a deltaX horizontally and \a deltaY vertically. + + \param deltaX The amount to scroll horizontally. + \param deltaY The amount to scroll vertically. +*/ + + +/*! + \fn void BView::ScrollTo(BPoint where) + \brief Scroll the view to the point specified by \a where. + + \param where The location to scroll the view to. +*/ + + +/*! + \fn void BView::ScrollWithMouseWheelDelta(BScrollBar* scrollBar, + float delta) + \brief Handle the scroll wheel changing over scrollbars. + + \note This method was not available in BeOS R5. + + - Extract the scrollbar change based on the mouse wheel \a delta into a + protected method of BView. + - The method is called from the MessageReceived() method of BScrollBar. + + With this change it is now a bit easier to scroll horizontally around the + system by putting the mouse cursor over a horizontal scrollbar and using + the wheel. +*/ + + +/*! + \fn status_t BView::SetEventMask(uint32 mask, uint32 options) + \brief Sets whether or not the view can accept mouse and keyboard + events when not in focus. + + If \a mask includes \c B_POINTER_EVENTS then the view will receive mouse + events even when the mouse isn't over the view and if it includes + \c B_KEYBOARD_EVENTS the view will receive keyboard events even if it + isn't in focus. + + The \a options mask options are as follows: + - \c B_NO_POINTER_HISTORY Tells App Server to only send the most recent + MouseMoved() event to the view sacrificing some granularity. + - \c B_FULL_POINTER_HISTORY Tells App Server to send all MouseMoved() + events to the view. + + \param mask The \a mask of \c B_POINTER_EVENTS and \c B_KEYBOARD_EVENTS + to set. + \param options Sets other event-handling options. + + \return \c B_OK if everything went fine or an error code, usually + \c B_ERROR if something went wrong. +*/ + + +/*! + \fn uint32 BView::EventMask() + \brief Returns the current event mask. + + \return The current event mask as a uint32. +*/ + + +/*! + \fn status_t BView::SetMouseEventMask(uint32 mask, uint32 options) + \brief Sets whether or not the view can accept mouse and keyboard + events when not in focus from within MouseDown() until the + following MouseUp() event. + + The \a options mask options are as follows: + - \c B_NO_POINTER_HISTORY Tells App Server to send only the most recent + MouseMoved() event to the view sacrificing mouse movement granularity. + - \c B_FULL_POINTER_HISTORY Tells App Server to send all MouseMoved() + events to the view. + - \c B_SUSPEND_VIEW_FOCUS Events normally sent to the focus view are + suppressed. While the mouse is held down, the keyboard is ignored. + The view receiving the MouseDown() messages doesn't have to be the + focus view to suppress focused messages. + - \c B_LOCK_WINDOW_FOCUS Prevents the attached window from losing its + focused state while the mouse is held down, even if the mouse leaves + the bounds of the window. + + \param mask The \a mask of \c B_POINTER_EVENTS and \c B_KEYBOARD_EVENTS + to set. + \param options Sets other event-handling options. + + \return \c B_OK if everything went fine or an error code, usually + \c B_ERROR if something went wrong. +*/ + + +//! @} + + +/*! + \name Graphics State Methods +*/ + + +//! @{ + + +/*! + \fn void BView::PushState() + \brief Saves the drawing state to the stack. + + The drawing state contains the following elements: + - local and global origins + - local and global scales + - local and global clipping regions + - the current drawing mode + - pen size and location + - the font context + - foreground and background color + - line cap and join modes + - miter limit + - stipple pattern + + A new state context is created after PushState() is called with a local scale + at 0, a local origin at (0, 0), and no clipping region. +*/ + + +/*! + \fn void BView::PopState() + \brief Restores the drawing state from the stack. +*/ + + +/*! + \fn void BView::SetOrigin(BPoint pt) + \brief Sets the origin in the view's coordinate system. + + \param pt The point to set the origin to. +*/ + + +/*! + \fn void BView::SetOrigin(float x, float y) + \brief Sets the origin in the view's coordinate system. + + \param x The x-coordinate to set the origin to. + \param y The y-coordinate to set the origin to. +*/ + + +/*! + \fn BPoint BView::Origin() const + \brief Returns the origin point in the view's coordinate system. + + \return The local origin point in the view's coordinate system. +*/ + + +/*! + \fn void BView::SetScale(float scale) const + \brief Sets the scale of the coordinate system the view uses for drawing. + + The default scale is 1.0. A \a scale value lower than 1.0 reduces the size of + the drawing coordinate system, a \a scale value greater than 1.0 magnifies + the coordinate system; for example, a \a scale value of 0.5 cuts the drawing + drawing area in half moving the drawing closer to the origin while a \a scale + value of 2.0 doubles the drawing area and moving it away from the origin. + + Updating the \a scale of view won't update previously drawn elements. + + SetScale() calls are not commutative unless you call them across different + drawing states as the following: + +\code + view->SetScale(2); + view->SetScale(2); + // view's scale is 2 + + view2->SetScale(2); + view2->PushState(); + view2->SetScale(2); + // view2's scale is 4 +\endcode + + /param scale The scale factor to set. +*/ + + +/*! + \fn float BView::Scale() const + \brief Return the current drawing scale. + + \return The current drawing scale. +*/ + + +/*! + \fn void BView::SetLineMode(cap_mode lineCap, join_mode lineJoin, + float miterLimit) + \brief Set line mode to use PostScript-style line cap and join modes. + + \a lineCap determines the shape of the endpoints of stroked paths while + \a lineJoin determines the shape of the corners where two lines meet. + + The default miter limit is 10.0 which gives an angle of 11.478341°. + + \param lineCap One of the following: + - \c B_ROUND_CAP A semicircle with diameter of line width is drawn at the + endpoint. + - \c B_BUTT_CAP A straight edge is drawn without extending beyond the endpoint. + - \c B_SQUARE_CAP A straight edge is drawn extending past the endpoint by half + the line width. + \param lineJoin One of the following: + - \c B_ROUND_JOIN Same as \c B_ROUND_CAP but for a join. + - \c B_MITER_JOIN The lines are extended until they meet. If angle that they + meet at is greater than the 2*arcsin(1/\a miterLimit) than a bevel join + is used instead. + - \c B_BEVEL_JOIN The area between the caps is filled with a triangle. + - \c B_BUTT_JOIN Same as \c B_BUTT_CAP but for a join. + - \c B_SQUARE_JOIN Same as \c B_SQUARE_CAP but for a join. + \param miterLimit Sets the cut off angle before a miter join becomes a bevel + join calculated by 2*arcsin(1/\a miterLimit). +*/ + + +/*! + \fn join_mode BView::LineJoinMode() const + \brief Returns the current line join mode. + + \return The current line join mode set to the view. +*/ + + +/*! + \fn cap_mode BView::LineCapMode() const + \brief Returns the current line cap mode. + + \return The current line cap mode set to the view. +*/ + + +/*! + \fn float BView::LineMiterLimit() const + \brief Returns the miter limit used for \c B_MITER_JOIN join mode. + + \return The current miter limit set to the view. +*/ + + +/*! + \fn void BView::SetDrawingMode(drawing_mode mode) + \brief Sets the drawing mode of the view. + + The default drawing mode is \c B_OP_COPY. + + \param mode Set to one of the following: + - \c B_OP_COPY + - \c B_OP_OVER + - \c B_OP_ERASE + - \c B_OP_INVERT + - \c B_OP_SELECT + - \c B_OP_ALPHA + - \c B_OP_MIN + - \c B_OP_MAX + - \c B_OP_ADD + - \c B_OP_SUBTRACT + - \c B_OP_BLEND +*/ + + +/*! + \fn drawing_mode BView::DrawingMode() const + \brief Return the current drawing_mode. + + \return The current drawing_mode. +*/ + + +/*! + \fn void BView::SetBlendingMode(source_alpha srcAlpha, + alpha_function alphaFunc) + \brief Set the blending mode which controls how transparency is used. + + \param srcAlpha Set to one of the following: + - \c B_CONSTANT_ALPHA Use the high color's alpha channel. + - \c B_PIXEL_ALPHA Use the alpha value of each pixel when drawing a bitmap. + \param alphaFunc Set to one of the following: + - \c B_ALPHA_OVERLAY Used for drawing a image with transparency over an opaque + background. + - \c B_ALPHA_COMPOSITE Used to composite two or more transparent images + together offscreen to produce a new image drawn using + \c B_ALPHA_OVERLAY mode. +*/ + + +/*! + \fn void BView::GetBlendingMode(source_alpha* srcAlpha, + alpha_function* alphaFunc) const + \brief Fill out \a srcAlpha and \a alphaFunc with the alpha mode and + alpha function of the view. + + \param[out] srcAlpha The alpha mode to fill out. + \param[out] alphaFunc The alpha function to fill out. +*/ + + +/*! + \fn void BView::MovePenTo(BPoint point) + \brief Move the pen to \a point in the view's coordinate system. + + \param point the location to move the pen to. +*/ + + +/*! + \fn void BView::MovePenTo(float x, float y) + \brief Move the pen to the point specified by \a x and \a y in the view's + coordinate system. + + \param x The horizontal coordinate to move the pen to. + \param y The vertical coordinate to move the pen to. +*/ + + +/*! + \fn void BView::MovePenBy(float x, float y) + \brief Move the pen by \a x pixels horizontally and \a y pixels vertically. + + \param x The number of pixels to move the pen horizontally. + \param y The number of pixels to move the pen vertically. +*/ + + +/*! + \fn BPoint BView::PenLocation() const + \brief Return the current pen location as a BPoint object. + + \return The current pen location in the view's coordinate system. +*/ + + +/*! + \fn void BView::SetPenSize(float size) + \brief Set the pen size to \a size. + + \param size The pen size to set. +*/ + + +/*! + \fn float BView::PenSize() const + \brief Return the current pen size. + + \return The current pen size as a float. +*/ + + +/*! + \fn void BView::SetHighColor(rgb_color color) + \brief Set the high color of the view. + + \param color The color to set. +*/ + + +/*! + \fn void BView::SetHighColor(uchar red, uchar green, uchar blue, + uchar alpha) + \brief Set the high color of the view. + + \param red The \a red component of the high color. + \param green The \a green component of the high color. + \param blue The \a blue component of the high color. + \param alpha The \a alpha component of the high color. +*/ + + +/*! + \fn rgb_color BView::HighColor() const + \brief Return the current high color. + + \return The current high color as an rgb_color struct. +*/ + + +/*! + \fn void BView::SetLowColor(rgb_color color) + \brief Set the low color of the view. + + \param color The color to set. +*/ + + +/*! + \fn void BView::SetLowColor(uchar red, uchar green, uchar blue, uchar alpha) + \brief Set the low color of the view. + + \param red The \a red component of the low color. + \param green The \a green component of the low color. + \param blue The \a blue component of the low color. + \param alpha The \a alpha component of the low color. +*/ + + +/*! + \fn rgb_color BView::LowColor() const + \brief Return the current low color. + + \return The current low color as an rgb_color struct. +*/ + + +/*! + \fn void BView::SetViewColor(rgb_color color) + \brief Set the view color of the view. + + \param color The color to set. +*/ + + +/*! + \fn void BView::SetViewColor(uchar red, uchar green, uchar blue, + uchar alpha) + \brief Set the view color of the view. + + \param red The \a red component of the view color. + \param green The \a green component of the view color. + \param blue The \a blue component of the view color. + \param alpha The \a alpha component of the view color. +*/ + + +/*! + \fn rgb_color BView::ViewColor() const + \brief Return the current view color. + + \return The current view color as an rgb_color struct. +*/ + + +/*! + \fn void BView::ForceFontAliasing(bool enable) + \brief Turn anti-aliasing on and off when printing. + + Typically want to turn font anti-aliasing off when printing by passing + \c true to this method and then turn it on again by passing in \c false. + + This method does not affect characters drawn to the screen. + + \param enable If \c true turn off anti-aliasing, if \c false turn on + anti-aliasing. +*/ + + +/*! + \fn void BView::SetFont(const BFont* font, uint32 mask) + \brief Set the font of the view. + + By passing \c B_FONT_ALL to the \a mask parameter as is the default all font + properties from \a font are set on the view. + + \param font A pointer to a BFont object to set. + \param mask A mask of the following values to determine what font properties to set: + - \c B_FONT_FAMILY_AND_STYLE + - \c B_FONT_SPACING + - \c B_FONT_SIZE + - \c B_FONT_ENCODING + - \c B_FONT_SHEAR + - \c B_FONT_FACE + - \c B_FONT_ROTATION + - \c B_FONT_FLAGS +*/ + + +/*! + \fn void BView::GetFont(BFont* font) const + \brief Fill out \a font with the font set to the view. + + \param[out] font The BFont object to fill out. +*/ + + +/*! + \fn void BView::GetFontHeight(font_height* height) const + \brief Fill out the font_height struct with the view font. + + \param[out] height The font_height struct to fill out. +*/ + + +/*! + \fn void BView::SetFontSize(float size) + \brief Set the size of the view's font to \a size. + + \param size The font size to set to the view in points. +*/ + + +/*! + \fn float BView::StringWidth(const char* string) const + \brief Return the width of \a string set in the font of the view. + + \param string The \a string to get the width of. + + \return The width of the string in the view's font as a float. +*/ + + +/*! + \fn float BView::StringWidth(const char* string, int32 length) const + \brief Return the width of \a string set in the font of the view up to + \a length characters. + + \param string The \a string to get the width of. + \param length The maximum number of characters in \a string to consider. + + \return The width of the string in the view's font as a float. +*/ + + +/*! + \fn void BView::GetStringWidths(char* stringArray[], int32 lengthArray[], + int32 numStrings, float widthArray[]) const + \brief Fill out widths of the strings in \a stringArray set in the font + of the view into \a widthArray. + + \param stringArray The array of strings to get the lengths of. + \param lengthArray The number of characters of the strings in \a stringArray + to consider. + \param numStrings The number of strings in \a stringArray. + \param widthArray The array to store the widths of the strings in + \a stringArray. +*/ + + +/*! + \fn void BView::TruncateString(BString* string, uint32 mode, float width) const + \brief Truncate \a string with truncation mode \a mode so that it is no wider + than \a width set in the view's font. + + When the string is truncated the missing characters are replaced by a + horizontal ellipses. + + \param string The string to truncate in place. + \param mode The truncation mode to use, one of the following: + - \c B_TRUNCATE_BEGINNING Truncate from the beginning of the string. + - \c B_TRUNCATE_MIDDLE Truncate from the middle of the string. + - \c B_TRUNCATE_END Truncate from the end of the string. + - \c B_TRUNCATE_SMART Truncate from anywhere based on the string content. + Not currently implemented. + \param width The maximum width to truncate the string to. +*/ + + +/*! + \fn void BView::ClipToPicture(BPicture* picture, BPoint where, bool sync) + \brief Intersects the current clipping region of the view with the pixels + of \a picture. + + BPicture instances are resolution independent, \a picture is effectively + drawn at the view's resolution and the bitmap produced is used to modify the + clipping region. + + The pixels that are at least partially opaque are the ones drawn by + \a picture. + + \param picture The BPicture object to intersect with. + \param where Offset in the view's coordinate system. + \param sync If \c false, this method will execute asynchronously. +*/ + + +/*! + \fn void BView::ClipToInversePicture(BPicture* picture, BPoint where, + bool sync) + \brief Intersects the current clipping region of the view with the pixels + outside of \a picture. + + \param picture The BPicture object to intersect with. + \param where Offset in the view's coordinate system. + \param sync If \c false, this method will execute asynchronously. + + \see ClipToPicture() +*/ + + +/*! + \fn void BView::GetClippingRegion(BRegion* region) const + \brief Fill out \a region with the view's clipping region. + + \param[out] region The BRegion object to fill out. +*/ + + +/*! + \fn void BView::ConstrainClippingRegion(BRegion* region) + \brief Set the clipping region the \a region restricting the area that the + view can draw in. + + The Application Server keeps track of the clipping region for each view + attached to a window so that the view can't draw outside of it, + consequently this method works only for view that are attached to a window. + + The default clipping region contains the visible area of the view. By passing + a region to this method the clipping area is further restricted. Passing in + \c NULL resets the clipping region back to the default. + + Calls to ConstrainClippingRegion() are not cumulative, each time this + method is called it replaces the old clipping region. + + \param region The region to set the clipping region to or \c NULL + to reset to default. +*/ + + +//! @} + + +/*! + \name Drawing Related Methods + + The view must be attached to the window for these methods to work unless + otherwise stated. Notes on specific methods are provided below: + + DrawBitmap() + + If the the image is bigger than the destination rectangle, it is scaled to fit. + + The asynchronous versions pass the image to Application Server and return + immediately. + + This can be more efficient in some cases for example to draw several bitmaps + at once and then call Sync() to tell Application Server to wait for them all + to finish drawing rather than waiting for each one to draw. + + DrawPicture() + + The asynchronous versions pass the picture to Application Server and return + immediately. + + This can be more efficient in some cases for example to draw several pictures + at once and then call Sync() to tell Application Server to wait for them all + to finish drawing rather than waiting for each one to draw. + + DrawPicture() doesn't alter the graphics state of the view nor do changes to + the graphics state of the view alter the BPicture object. What the picture + will look like depends on the graphics parameters that were in effect when the + picture was recorded. + + DrawString() + + The \a string is drawn in the view's current font and is modified by + the other parameters of the font such as it's direction (left-to-right or + right-to-left), rotation, spacing, shear, etc. The \a string is always drawn + left to right even if it's text direction is set to right-to-left mode. + + Drawing a string is fastest in \c B_OP_COPY mode and anti-aliasing can + produce undesirable effects when a string is draw in other modes, especially + if the string is drawn in the same location repeatedly. + + DrawString() doesn't erase before drawing. +*/ + + +//! @{ + + +/*! + \fn void BView::DrawBitmapAsync(const BBitmap* bitmap, BRect bitmapRect, + BRect viewRect, uint32 options) + \brief Draws \a bitmap on the view within \a viewRect asynchronously. + + \param bitmap The bitmap to draw onto the view. + \param bitmapRect The portion of the bitmap to draw in the bitmap's + coordinate system. + \param viewRect The area in the view's coordinate system to draw the + bitmap in. + \param options ?? +*/ + + +/*! + \fn void BView::DrawBitmapAsync(const BBitmap* bitmap, BRect bitmapRect, + BRect viewRect) + \brief Draws \a bitmap on the view within \a viewRect asynchronously. + + \param bitmap The bitmap to draw onto the view. + \param bitmapRect The portion of the bitmap to draw in the bitmap's + coordinate system. + \param viewRect The area in the view's coordinate system to draw the + bitmap in. +*/ + + +/*! + \fn void BView::DrawBitmapAsync(const BBitmap* bitmap, BRect viewRect) + \brief Draws \a bitmap on the view within \a viewRect asynchronously. + + \param bitmap The bitmap to draw onto the view. + \param viewRect The area in the view's coordinate system to draw the + bitmap in. +*/ + + +/*! + \fn void BView::DrawBitmapAsync(const BBitmap* bitmap, BPoint where) + \brief Draws \a bitmap on the view offset by \a where asynchronously. + + \param bitmap The bitmap to draw onto the view. + \param where The location to draw the bitmap in the view's coordinate system. +*/ + + +/*! + \fn void BView::DrawBitmapAsync(const BBitmap* bitmap) + \brief Draws \a bitmap on the view asynchronously. + + \param bitmap The bitmap to draw onto the view. +*/ + + +/*! + \fn void BView::DrawBitmap(const BBitmap* bitmap, BRect bitmapRect, + BRect viewRect, uint32 options) + \brief brief Draws \a bitmap on the view within \a viewRect. + + \param bitmap The bitmap to draw onto the view. + \param bitmapRect The portion of the bitmap to draw in the bitmap's + coordinate system. + \param viewRect The area in the view's coordinate system to draw the + bitmap in. + \param options ?? +*/ + + +/*! + \fn void BView::DrawBitmap(const BBitmap* bitmap, BRect bitmapRect, + BRect viewRect) + \brief Draws \a bitmap on the view within \a viewRect. + + \param bitmap The bitmap to draw onto the view. + \param bitmapRect The portion of the bitmap to draw in the bitmap's + coordinate system. + \param viewRect The area in the view's coordinate system to draw the + bitmap in. +*/ + + +/*! + \fn void BView::DrawBitmap(const BBitmap* bitmap, BRect viewRect) + \brief Draws \a bitmap on the view within \a viewRect. + + \param bitmap The bitmap to draw onto the view. + \param viewRect The area in the view's coordinate system to draw the + bitmap in. +*/ + + +/*! + \fn void BView::DrawBitmap(const BBitmap* bitmap, BPoint where) + \brief Draws \a bitmap on the view offset by \a where. + + \param bitmap The bitmap to draw onto the view. + \param where The location to draw the bitmap in the view's coordinate system. +*/ + + +/*! + \fn void BView::DrawBitmap(const BBitmap* bitmap) + \brief Draws \a bitmap on the view. + + \param bitmap The bitmap to draw onto the view. +*/ + + +/*! + \fn void BView::DrawChar(char c) + \brief Draws character \a c onto to the view at the current pen position. + + The character is drawn in the view's current font. + + \param c The character to draw. +*/ + + +/*! + \fn void BView::DrawChar(char c, BPoint location) + \brief Draws character \a c at the specified \a location in the view. + + The character is drawn in the view's current font. + + \param c The character to draw. + \param location The location in the view to draw the character. +*/ + + +/*! + \fn void BView::DrawString(const char* string, escapement_delta* delta) + \brief Draw \a string onto the view at the current pen position. + + \param string The string to draw. + \param delta Adds additional width to each character according to the + following fields: + - nonspace(float) The amount of width to add to characters with visible + glyphs. + - space(float) The amount of width to add to characters with escapements + but don't have visible glyphs. +*/ + + +/*! + \fn void BView::DrawString(const char* string, BPoint location, + escapement_delta* delta) + \brief Draw \a string onto the view at the specified \a location in the view. + + \param string The string to draw. + \param location The location in the view to draw the string. + \param delta Adds additional width to each character according to the + following fields: + - nonspace(float) The amount of width to add to characters with visible + glyphs. + - space(float) The amount of width to add to characters with escapements + but don't have visible glyphs. +*/ + + +/*! + \fn void BView::DrawString(const char* string, int32 length, + escapement_delta* delta) + \brief Draw \a string up to \a length characters onto the view at the current + pen position. + + \param string The string to draw. + \param length The maximum number of characters in \a string to draw. + \param delta Adds additional width to each character according to the + following fields: + - nonspace(float) The amount of width to add to characters with visible + glyphs. + - space(float) The amount of width to add to characters with escapements + but don't have visible glyphs. +*/ + + +/*! + \fn void BView::DrawString(const char* string, int32 length, BPoint location, + escapement_delta* delta) + \brief Draw \a string up to \a length characters onto the view at the + specified \a location in the view. + + \param string The string to draw. + \param length The maximum number of characters in \a string to draw. + \param location The location in the view to draw the string. + \param delta Adds additional width to each character according to the + following fields: + - nonspace(float) The amount of width to add to characters with visible + glyphs. + - space(float) The amount of width to add to characters with escapements + but don't have visible glyphs. +*/ + + +/*! + \fn void BView::DrawString(const char* string, const BPoint* locations, + int32 locationCount) + \brief Draw \a string \a locationCount times at the specified \a locations. + + \param string The string to draw. + \param locations A pointer to an array of BPoint objects to draw the string. + \param locationCount The number of elements in \a locations. +*/ + + +/*! + \fn void BView::DrawString(const char* string, int32 length, + const BPoint* locations, int32 locationCount) + \brief Draw \a string up to \a length characters \a locationCount times at the + specified \a locations. + + \param string The string to draw. + \param length The maximum number of characters in \a string to draw. + \param locations A pointer to an array of BPoint objects to draw the string. + \param locationCount The number of elements in \a locations. +*/ + + +/*! + \fn void BView::StrokeEllipse(BPoint center, float xRadius, float yRadius, + ::pattern pattern) + \brief Stroke the outline of an ellipse starting at \a center with a + horizontal radius of \a xRadius and a vertical radius of \a yRadius. + + \param center The center point. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::StrokeEllipse(BRect rect, ::pattern pattern) + \brief Stroke the outline of an ellipse inscribed within \a rect. + + \param rect The area within which to inscribe the shape. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillEllipse(BPoint center, float xRadius, float yRadius, + ::pattern pattern) + \brief Fill an ellipse starting at \a center with a horizontal radius + of \a xRadius and a vertical radius of \a yRadius. + + \param center The center point. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillEllipse(BRect rect, ::pattern pattern) + \brief Fill an ellipse inscribed within \a rect. + + \param rect The area within which to inscribe the shape. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillEllipse(BPoint center, float xRadius, float yRadius, + const BGradient& gradient) + \brief Fill an ellipse with the specified \a gradient pattern starting at + \a center with a horizontal radius of \a xRadius and a vertical radius + of \a yRadius. + + \param center The center point. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param gradient The gradient pattern to fill the ellipse with. +*/ + + +/*! + \fn void BView::FillEllipse(BRect rect, const BGradient& gradient) + \brief Fill an ellipse with the specified \a gradient pattern inscribed within + \a rect. + + \param rect The area within which to inscribe the shape. + \param gradient The gradient pattern to fill the ellipse with. +*/ + + +/*! + \fn void BView::StrokeArc(BPoint center, float xRadius, float yRadius, + float startAngle, float arcAngle, ::pattern pattern) + \brief Stroke the outline of an arc starting at \a center with a + horizontal radius of \a xRadius and a vertical radius of \a yRadius + starting at \a startAngle and drawing \a arcAngle degrees. + + \param center The center point. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param startAngle The angle to begin drawing at. + \param arcAngle The number of degrees of the arc to draw. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::StrokeArc(BRect rect, float startAngle, float arcAngle, + ::pattern pattern) + \brief Stroke the outline of an arc inscribed within \a rect starting at + \a startAngle and drawing \a arcAngle degrees. + + \param rect The area within which to inscribe the shape. + \param startAngle The angle to begin drawing at. + \param arcAngle The number of degrees of the arc to draw. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillArc(BPoint center, float xRadius, float yRadius, + float startAngle, float arcAngle, ::pattern pattern) + \brief Fill an arc starting at \a center with a horizontal radius of + \a xRadius and a vertical radius of \a yRadius starting at + \a startAngle and drawing \a arcAngle degrees. + + \param center The center point. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param startAngle The angle to begin drawing at. + \param arcAngle The number of degrees of the arc to draw. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillArc(BPoint center, float xRadius, float yRadius, + float startAngle, float arcAngle, const BGradient& gradient) + \brief Fill an arc with the specified \a gradient pattern starting at + \a center with a horizontal radius of \a xRadius and a vertical + radius of \a yRadius starting at \a startAngle and drawing + \a arcAngle degrees. + + \param center The center point. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param startAngle The angle to begin drawing at. + \param arcAngle The number of degrees of the arc to draw. + \param gradient The gradient pattern to fill the arc with. +*/ + + +/*! + \fn void BView::FillArc(BRect rect, float startAngle, float arcAngle, + ::pattern pattern) + \brief Fill an arc inscribed within \a rect starting at startAngle and + drawing \a arcAngle degrees. + + \param rect The area within which to inscribe the shape. + \param startAngle The angle to begin drawing at. + \param arcAngle The number of degrees of the arc to draw. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillArc(BRect rect, float startAngle, float arcAngle, + const BGradient& gradient) + \brief Fill an arc with the specified \a gradient pattern inscribed within + \a rect starting at startAngle and drawing \a arcAngle degrees. + + \param rect The area within which to inscribe the shape. + \param startAngle The angle to begin drawing at. + \param arcAngle The number of degrees of the arc to draw. + \param gradient The gradient pattern to fill the arc with. +*/ + + +/*! + \fn void BView::StrokeBezier(BPoint* controlPoints, ::pattern pattern) + \brief Stroke a bezier curve. + + \param controlPoints The list of points that form the bezier curve. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillBezier(BPoint* controlPoints, ::pattern pattern) + \brief Fill a bezier curve. + + \param controlPoints The list of points that form the bezier curve. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillBezier(BPoint* controlPoints, const BGradient& gradient) + + \brief Fill a bezier curve. + + \param controlPoints The list of points that form the bezier curve. + \param gradient The gradient pattern to fill the bezier curve with. +*/ + + +/*! + \fn void BView::StrokePolygon(const BPolygon* polygon, bool closed, ::pattern pattern) + \brief Stroke a polygon shape. + + \param polygon The polygon shape to stroke. + \param closed Whether or not the last line of the polygon should intersect + with the initial point. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::StrokePolygon(const BPoint* pointArray, int32 numPoints, + bool closed, ::pattern pattern) + \brief Stroke a polygon shape made up of points specified by \a pointArray. + + \param pointArray An array of points that specify the vertices of the polygon. + \param numPoints The number of points in \a pointArray. + \param closed Whether or not the last line of the polygon should intersect + with the initial point. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::StrokePolygon(const BPoint* pointArray, int32 numPoints, + BRect bounds, bool closed, ::pattern pattern) + \brief Stroke a polygon shape made up of points specified by \a pointArray + inscribed by \a bounds. + + \param pointArray An array of points that specify the vertices of the polygon. + \param numPoints The number of points in \a pointArray. + \param bounds The smallest rectangle that encloses the points in \a pointArray. + \param closed Whether or not the last line of the polygon should intersect + with the initial point. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillPolygon(const BPolygon* polygon, ::pattern pattern) + \brief Fill a polygon shape. + + \param polygon The polygon shape to fill. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillPolygon(const BPolygon* polygon, + const BGradient& gradient) + \brief Fill a polygon shape with the specified \a gradient pattern. + + \param polygon The polygon shape to fill. + \param gradient The gradient pattern to fill the polygon with. +*/ + + +/*! + \fn void BView::FillPolygon(const BPoint* pointArray, int32 numPoints, + ::pattern pattern) + \brief Fill a polygon shape made up of points specified by \a pointArray. + + \param pointArray An array of points that specify the vertices of the polygon. + \param numPoints The number of points in \a pointArray. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillPolygon(const BPoint* pointArray, int32 numPoints, + const BGradient& gradient) + \brief Fill a polygon shape made up of points specified by \a pointArray + with the specified \a gradient pattern. + + \param pointArray An array of points that specify the vertices of the + polygon. + \param numPoints The number of points in \a pointArray. + \param gradient The gradient pattern to fill the polygon with. +*/ + + +/*! + \fn void BView::FillPolygon(const BPoint* pointArray, int32 numPoints, + BRect bounds, ::pattern pattern) + \brief Fill a polygon shape made up of points specified by \a pointArray + inscribed by \a bounds. + + \param pointArray An array of points that specify the vertices of the + polygon. + \param numPoints The number of points in \a pointArray. + \param bounds The smallest rectangle that encloses the points in + \a pointArray. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillPolygon(const BPoint* pointArray, int32 numPoints, + BRect bounds, const BGradient& gradient) + \brief Fill a polygon shape made up of points specified by \a pointArray + inscribed by \a bounds with the specified \a gradient pattern. + + \param pointArray An array of points that specify the vertices of the + polygon. + \param numPoints The number of points in \a pointArray. + \param bounds The smallest rectangle that encloses the points in + \a pointArray. + \param gradient The gradient pattern to fill the polygon with. +*/ + + +/*! + \fn void BView::StrokeRect(BRect rect, ::pattern pattern) + \brief Stroke the rectangle specified by \a rect. + + \param rect The rectangular area to stroke. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillRect(BRect rect, ::pattern pattern) + \brief Fill the rectangle specified by \a rect. + + \param rect The rectangular area to fill. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillRect(BRect rect, const BGradient& gradient) + \brief Fill the rectangle specified by \a rect with the specified + \a gradient pattern. + + \param rect The rectangular area to fill. + \param gradient The gradient pattern to fill the rectangle with. +*/ + + +/*! + \fn void BView::StrokeRoundRect(BRect rect, float xRadius, float yRadius, + ::pattern pattern) + \brief Stroke the rounded rectangle with horizontal radius \a xRadius and + vertical radius \a yRadius. + + \param rect The rectangular area to stroke the round rect within. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillRoundRect(BRect rect, float xRadius, float yRadius, + ::pattern pattern) + \brief Fill the rounded rectangle with horizontal radius \a xRadius and + vertical radius \a yRadius. + + \param rect The rectangular area to fill the round rect within. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillRoundRect(BRect rect, float xRadius, float yRadius, + const BGradient& gradient) + \brief Fill the rounded rectangle with horizontal radius \a xRadius and + vertical radius \a yRadius with the specified \a gradient pattern. + + \param rect The rectangular area to fill the round rect within. + \param xRadius The horizontal radius. + \param yRadius The vertical radius. + \param gradient The gradient pattern to fill the round rect with. +*/ + + +/*! + \fn void BView::FillRegion(BRegion* region, ::pattern pattern) + \brief Fill \a region. + + \param region The \a region to fill. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillRegion(BRegion* region, const BGradient& gradient) + \brief Fill \a region with the specified \a gradient pattern. + + \param region The \a region to fill. + \param gradient The gradient pattern to fill the \a region with. +*/ + + +/*! + \fn void BView::StrokeTriangle(BPoint point1, BPoint point2, BPoint point3, + BRect bounds, ::pattern pattern) + \brief Stroke the triangle specified by points \a point1, \a point2, and + \a point3 and enclosed by \a bounds. + + \param point1 The first point of the triangle. + \param point2 The second point of the triangle. + \param point3 The third point of the triangle. + \param bounds The rectangular area that encloses the triangle. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::StrokeTriangle(BPoint point1, BPoint point2, BPoint point3, + ::pattern pattern) + \brief Stroke the triangle specified by points \a point1, \a point2, + and \a point3. + + \param point1 The first point of the triangle. + \param point2 The second point of the triangle. + \param point3 The third point of the triangle. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillTriangle(BPoint point1, BPoint point2, BPoint point3, + ::pattern pattern) + \brief Fill the triangle specified by points \a point1, \a point2, + and \a point3. + + \param point1 The first point of the triangle. + \param point2 The second point of the triangle. + \param point3 The third point of the triangle. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillTriangle(BPoint point1, BPoint point2, BPoint point3, + const BGradient& gradient) + \brief Fill the triangle specified by points \a point1, \a point2, + and \a point3 with the specified \a gradient pattern. + + \param point1 The first point of the triangle. + \param point2 The second point of the triangle. + \param point3 The third point of the triangle. + \param gradient The gradient pattern to fill the triangle with. +*/ + + +/*! + \fn void BView::FillTriangle(BPoint point1, BPoint point2, BPoint point3, + BRect bounds, ::pattern pattern) + \brief Fill the triangle specified by points \a point1, \a point2, + and \a point3 and enclosed by \a bounds. + + \param point1 The first point of the triangle. + \param point2 The second point of the triangle. + \param point3 The third point of the triangle. + \param bounds The rectangular area that encloses the triangle. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillTriangle(BPoint point1, BPoint point2, BPoint point3, + BRect bounds, const BGradient& gradient) + \brief Fill the triangle specified by points \a point1, \a point2, + and \a point3 and enclosed by \a bounds with the specified + \a gradient pattern. + + \param point1 The first point of the triangle. + \param point2 The second point of the triangle. + \param point3 The third point of the triangle. + \param bounds The rectangular area that encloses the triangle. + \param gradient The gradient pattern to fill the triangle with. +*/ + + +/*! + \fn void BView::StrokeLine(BPoint toPoint, ::pattern pattern) + \brief Stroke a line from the current pen location to the point \a toPoint. + + \param toPoint The end point of the line. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::StrokeLine(BPoint start, BPoint end, ::pattern pattern) + \brief Stroke a line from point \a start to point \a end. + + \param start The start point of the line. + \param end The end point of the line. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::StrokeShape(BShape* shape, ::pattern pattern) + \brief Stroke \a shape. + + \param shape The \a shape to stroke. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillShape(BShape* shape, ::pattern pattern) + \brief Fill \a shape. + + \param shape The \a shape to fill. + \param pattern One of the following: + - \c B_SOLID_HIGH + - \c B_SOLID_LOW + - \c B_MIXED_COLORS +*/ + + +/*! + \fn void BView::FillShape(BShape* shape, const BGradient& gradient) + \brief Fill \a shape with the specified \a gradient pattern. + + \param shape The \a shape to fill. + \param gradient The gradient pattern to fill the \a shape with. +*/ + + +/*! + \fn void BView::BeginLineArray(int32 count) + \brief Begin a line array of up to \a count lines. + + This is a more efficient way of drawing a large number of lines than calling + StrokeLine() repeatedly. First call BeginLineArray() to begin drawing lines, + then call AddLine() for each line you wish to draw, and finally call + EndLineArray() to finish the line array and draw the lines. + + These methods don't move the current pen location or change the high or low + colors of the view. \a count should be close to the number of lines you wish + to draw and should be below 256 to draw efficiently. + + \param count The maximum number of lines in the line array to draw. + + \see StrokeLine() +*/ + + +/*! + \fn void BView::AddLine(BPoint start, BPoint end, rgb_color color); + \brief Add a line to the line array from point \a pt0 to point \a pt1. + + \param start The \a start point of the line. + \param end The \a end point of the line. + \param color The line \a color. +*/ + + +/*! + \fn void BView::EndLineArray() + \brief End the line array drawing the lines. +*/ + + +/*! + \fn void BView::SetDiskMode(char* filename, long offset) + \brief Unimplemented. +*/ + + +/*! + \fn void BView::BeginPicture(BPicture* picture) + \brief Begins sending drawing instructions to \a picture. + + The \a BPicture object is cleared and any successive drawing instructions sent + to the view are redirected to \a picture until EndPicture() is called. To + append drawing instructions to a BPicture object without clearing it first + call AppendToPicture() instead. + + The view doesn't display anything to the screen while it's recording to \a + picture. Use the DrawPicture() method to render the \a picture. + + Only drawing instructions performed directly on the view, not it's child views + are send to the BPicture object and BPicture captures only primitive graphics + operations. The view must be attached to a window for the drawing instruction + to be recorded. Drawing instructions are recorded even if the view is hidden or + resides outside the clipping region or the window is off-screen. + + \param picture The BPicture object to record drawing instructions to. +*/ + + +/*! + \fn void BView::AppendToPicture(BPicture* picture) + \brief Appends drawing instructions to \a picture without clearing it first. + + \param picture The BPicture object to record drawing instructions to. +*/ + + +/*! + \fn BPicture* BView::EndPicture() + \brief Ends the drawing instruction recording session and returns the + BPicture object passed to BeginPicture() or AppendToPicture(). + + \return The BPicture object passed to BeginPicture() or AppendToPicture(). +*/ + + +/*! + \fn void BView::SetViewBitmap(const BBitmap* bitmap, BRect srcRect, + BRect dstRect, uint32 followFlags, uint32 options) + \brief Sets the background \a bitmap of the view. + + All drawing to the view occurs over \a bitmap. Any visible regions not + covered by \a bitmap are filled with the current background color. + + Once \a bitmap has been passed in and this method returns the caller may + safely delete the object. + + \param bitmap The background bitmap to set to the view. + \param srcRect Specifies the area of \a bitmap to use. + \param dstRect Specifies the area of the view to set \a bitmap to. + \param followFlags Specifies the as the view is resized. See the BView + constructor for more details. + \param options Specifies additional view options. The only option currently + available is \c B_TILE_BITMAP which tiles the bitmap across the view. +*/ + + +/*! + \fn void BView::SetViewBitmap(const BBitmap* bitmap, uint32 followFlags, + uint32 options) + \brief Sets the background \a bitmap of the view. + + All drawing to the view occurs over \a bitmap. Any visible regions not + covered by \a bitmap are filled with the current background color. + + Once \a bitmap has been passed in and this method returns the caller may + safely delete the object. + + \param bitmap The background bitmap to set to the view. + \param followFlags Specifies the as the view is resized. See the BView + constructor for more details. + \param options Specifies additional view options. The only option currently + available is \c B_TILE_BITMAP which tiles the bitmap across the view. +*/ + + +/*! + \fn void BView::ClearViewBitmap() + \brief Clears the background bitmap of the view if it has one. +*/ + + +/*! + \fn status_t BView::SetViewOverlay(const BBitmap* overlay, BRect srcRect, + BRect dstRect, rgb_color* colorKey, uint32 followFlags, uint32 options) + \brief Sets the \a overlay bitmap of the view. + + \a colorKey specifies which color pixels in \a overlay are treated as transparent + allowing the pixels of the view to show through. + + Once \a overlay has been passed in and this method returns the caller may + safely delete the object. + + \param overlay The overlay bitmap to set to the view. + \param srcRect Specifies the area of \a overlay to use. + \param dstRect Specifies the area of the view to set \a overlay to. + \param colorKey The color in \a overlay to treat as transparent. + \param followFlags Specifies the as the view is resized. See the BView + constructor for more details. + \param options Specifies additional view options. The only option currently + available is \c B_TILE_BITMAP which tiles the bitmap across the view. +*/ + + +/*! + \fn status_t BView::SetViewOverlay(const BBitmap* overlay, + rgb_color* colorKey, uint32 followFlags, uint32 options) + \brief Sets the \a overlay bitmap of the view. + + \a colorKey specifies which color pixels in \a overlay are treated as transparent + allowing the pixels of the view to show through. + + Once \a overlay has been passed in and this method returns the caller may + safely delete the object. + + \param overlay The overlay bitmap to set to the view. + \param colorKey The color in \a overlay to treat as transparent. + \param followFlags Specifies the as the view is resized. See the BView + constructor for more details. + \param options Specifies additional view options. The only option currently + available is \c B_TILE_BITMAP which tiles the bitmap across the view. +*/ + + +/*! + \fn void BView::ClearViewOverlay() + \brief Clears the overlay bitmap of the view if it has one. +*/ + + +/*! + \fn void BView::CopyBits(BRect src, BRect dst) + \brief Copy the bits from the \a src rectangle to the \a dst rectangle in the + view's coordinate system. + + If the rectangles are of different sizes than \a src is scaled to fit. \a src + is clipped if a part of \a dst lies outside of the visible region of the view. + Only the visible portions of \a src are copied. + + The view must be attached to a window for this method to work. + + \param src The source rectangle to copy bits from. + \param dst The destination rectangle to copy bits to. +*/ + + +/*! + \fn void BView::DrawPicture(const BPicture* picture) + \brief Draws the \a picture at the view's current pen position. + + \param picture The BPicture object to draw. +*/ + + +/*! + \fn void BView::DrawPicture(const BPicture* picture, BPoint where) + \brief Draws the \a picture at the location in the view specified by \a where. + + \param picture The BPicture object to draw. + \param where The point on the view to draw \a picture. +*/ + + +/*! + \fn void BView::DrawPicture(const char* filename, long offset, BPoint where) + \brief Draws the \a picture from the file specified by \a filename offset by + \a offset bytes at the location in the view specified by \a where. + + \param filename The filename of the file containing the picture to draw. + \param where The point on the view to draw the picture. + \param offset The number of bytes to offset in the file to find the picture. +*/ + + +/*! + \fn void BView::DrawPictureAsync(const BPicture* picture) + \brief Draws the \a picture at the view's current pen position. + + \param picture The BPicture object to draw. +*/ + + +/*! + \fn void BView::DrawPictureAsync(const BPicture* picture, BPoint where) + \brief Draws the \a picture at the location in the view specified by \a where. + + \param picture The BPicture object to draw. + \param where The point on the view to draw \a picture. +*/ + + +/*! + \fn void BView::DrawPictureAsync(const char* filename, long offset, BPoint where) + \brief Draws the \a picture from the file specified by \a filename offset by + \a offset bytes at the location in the view specified by \a where. + + \param filename The filename of the file containing the picture to draw. + \param where The point on the view to draw the picture. + \param offset The number of bytes to offset in the file to find the picture. +*/ + + +/*! + \fn void BView::Invalidate(BRect invalRect) + \brief Sends a message to App Server to redraw the portion of the view + specified by \a invalRect. + + \param invalRect The rectangular area of the view to redraw. +*/ + + +/*! + \fn void BView::Invalidate(const BRegion* region) + \brief Sends a message to App Server to redraw the portion of the view + specified by \a region. + + \param region The region of the view to redraw. +*/ + + +/*! + \fn void BView::Invalidate() + \brief Sends a message to App Server to redraw the view. +*/ + + +/*! + \fn void BView::InvertRect(BRect rect) + \brief Inverts the colors within \a rect. + + This method is often used to draw a highlighted selection in a view. + + \param rect The rectangular area in the view to invert the colors of. +*/ + + +//! @} + + +/*! + \name View Hierarchy Methods +*/ + + +//! @{ + + +/*! + \fn void BView::AddChild(BView* child, BView* before) + \brief Adds \a child to the view hierarchy immediately before \a before. + + A view may only have one parent at a time so \a child must not have already + been added to the view hierarchy. if \a before \c NULL then \a child is added + to the end of the tree. If the view is attached to a window \a child and all + of its descendent views also become attached to the window invoking an + AttachedToWindow() method on each view. + + \param child The child view to add. + \param before The sibling view to add \a child before. +*/ + + +/*! + \fn bool BView::AddChild(BLayoutItem* child) + \brief Add the \a child layout item to the view hierarchy. + + \param child The child layout item to add. + \return Whether or not \a child was added to the view layout hierarchy. +*/ + + +/*! + \fn bool BView::RemoveChild(BView* child) + \brief Removes \a child from the view hierarchy. + + \param child The child view to remove. + \return Whether or not \a child was removed from the view hierarchy. +*/ + + +/*! + \fn int32 BView::CountChildren() const + \brief Returns the number of child views that this view has. + + \return The number of child views. +*/ + + +/*! + \fn BView* BView::ChildAt(int32 index) const + \brief Returns a pointer to the child view found at \a index. + + \param index The index of the child view to return a pointer of. + + \return A pointer to the child view at \a index or \c NULL if not found. +*/ + + +/*! + \fn BView* BView::NextSibling() const + \brief Returns a pointer to the next sibling view. + + \return A pointer to the next sibling view or \a NULL if not found. +*/ + + +/*! + \fn BView* BView::PreviousSibling() const + \brief Returns a pointer to the previous sibling view. + + \return A pointer to the previous sibling view or \a NULL if not found. +*/ + + +/*! + \fn bool BView::RemoveSelf() + \brief Removes the view and all child views from the view hierarchy. + + \returns Whether or not the view was removed from the view hierarchy. +*/ + + +/*! + \fn BView* BView::Parent() const + \brief Returns a pointer to the view's parent. + + \return A pointer to the parent view or \c NULL if not attached. +*/ + + +/*! + \fn BView* BView::FindView(const char* name) const + \brief Returns the view in the view hierarchy with the specified \a name. + + \return The view in the view hierarchy with the specified \a name or \c NULL + if not found. +*/ + + +//! @} + + +/*! + \name View Frame Alteration Methods + + As a view's frame rectangle must be aligned to pixel values all parameters are + rounded to the nearest integer. If the view isn't attached these methods alter the + frame rectangle without triggering FrameMoved(), FrameResized() or Invalidate(). +*/ + + +//! @{ + + +/*! + \fn void BView::MoveBy(float deltaX, float deltaY) + \brief Moves the view \a deltaX pixels horizontally and \a deltaY pixels + vertically in the parent view's coordinate system. + + \param deltaX The number of pixels to move the view horizontally. + \param deltaY The number of pixels to move the view vertically. +*/ + + +/*! + \fn void BView::MoveTo(BPoint where) + \brief Move the view to the location specified by \a where in the parent + view's coordinate system. + + \param where The location to move the view to. +*/ + + +/*! + \fn void BView::MoveTo(float x, float y) + \brief Move the view to the coordinates specified by \a x in the horizontal + dimension and \a y in the vertical dimension in the parent view's + coordinate system. + + \param x The horizontal coordinate to move the view to. + \param y The vertical coordinate to move the view to. +*/ + + +/*! + \fn void BView::ResizeBy(float deltaWidth, float deltaHeight) + \brief Resize the view by \a deltaWidth horizontally and \a deltaHeight + vertically without moving the top left corner of the view. + + \param deltaWidth The number of pixels to resize the view by horizontally. + \param deltaHeight The number of pixels to resize the view by vertically. +*/ + + +/*! + \fn void BView::ResizeTo(float width, float height) + \brief Resize the view to the specified \a width and \a height. + + \param width The width to resize the view to. + \param height The height to resize the view to. +*/ + + +/*! + \fn void BView::ResizeTo(BSize size) + \brief Resize the view to the dimension specified by \a size. + + \param size The \a size to resize the view to. +*/ + + +//! @} + + +/*! + \fn status_t BView::GetSupportedSuites(BMessage* data) + \brief Reports the suites of messages and specifiers understood by the view. + + \param data The message to use to report the suite of messages and specifiers. + + \see BHandler::GetSupportedSuites() +*/ + + +/*! + \fn BHandler* BView::ResolveSpecifier(BMessage* message, int32 index, + BMessage* specifier, int32 what, const char* property) + \brief Determine the proper handler for a scripting message. + + \see BHandler::ResolveSpecifier() +*/ + + /*! \fn status_t BView::Perform(perform_code code, void* _data) \brief Perform some action. (Internal Method) @@ -218,6 +3428,16 @@ */ +/*! + \name Layout Methods + + \note These methods were not available in BeOS R5. +*/ + + +//! @{ + + /*! \fn BSize BView::MinSize() \brief Get the minimum size of the view. @@ -283,7 +3503,7 @@ /*! \fn void BView::SetLayout(BLayout* layout) - \brief Set the \a layout of the view. + \brief Sets the \a layout of the view. \param layout The \a layout to set. */ @@ -297,3 +3517,133 @@ */ +/*! + \fn void BView::InvalidateLayout(bool descendants) + \brief Invalidate layout. + + \param descendants Also invalidate its children views. +*/ + + +/*! + \fn void BView::EnableLayoutInvalidation() + \brief Enable layout invalidation. +*/ + + +/*! + \fn void BView::DisableLayoutInvalidation() + \brief Disable layout invalidation. +*/ + + +/*! + \fn bool BView::IsLayoutInvalidationDisabled() + \brief Returns whether or not layout invalidation is disabled. + + \return \c true of layout invalidation is disabled, \c false otherwise. +*/ + + +/*! + \fn bool BView::IsLayoutValid() const + \brief Returns whether or not the layout is valid. + + \brief Returns \c true if the layout is valid, \c false otherwise. +*/ + + +/*! + \fn void BView::ResetLayoutInvalidation() + \brief Service call for BView derived classes re-enabling + InvalidateLayout() notifications. + + BLayout and BView will avoid calling InvalidateLayout on views that have + already been invalidated, but if the view caches internal layout information + which it updates in methods other than DoLayout(), it has to invoke this + method, when it has done so, since otherwise the information might become + obsolete without the layout noticing. +*/ + + +/*! + \fn void BView::Layout(bool force) + \brief Layout the view. + + \param force If \c true layout even if valid. +*/ + + +/*! + \fn void BView::Relayout() + \brief Relayout the view. +*/ + + +/*! + \fn void BView::DoLayout() + \brief Layout view within the layout context. +*/ + + +//! @} + + +/*! + \name Tool Tip Methods + + \note These methods were not available in BeOS R5. +*/ + + +//! @{ + + +/*! + \fn void BView::SetToolTip(const char* text) + \brief Set the tool tip of the view to \a text. + + \param text The \a text to set the view to or \c NULL or blank to unset. +*/ + + +/*! + \fn void BView::SetToolTip(BToolTip* tip) + \brief Set the tool tip of the view to the \a tip object. + + \param tip The tool tip object to set the view to or \c NULL to unset. +*/ + + +/*! + \fn BToolTip* BView::ToolTip() const + \brief Return the tool tip set to the view or \c NULL if not set. + + \return The BToolTip object set to the view. +*/ + + +/*! + \fn void BView::ShowToolTip(BToolTip* tip) + \brief Show the tool tip at the current mouse position. + + \param tip The BToolTip object to show. +*/ + + +/*! + \fn void BView::HideToolTip() + \brief Hide the view's tool tip. +*/ + + +/*! + \fn bool BView::GetToolTipAt(BPoint point, BToolTip** _tip) + \brief Point \a _tip with the view's tool tip. + + \param point Currently unused. + \param _tip A pointer to a pointer to a BToolTip object to set. +*/ + + +//! @} diff --git a/headers/libs/ncurses/termcap.h b/headers/libs/ncurses/termcap.h new file mode 100644 index 0000000000..ad2d13d1ee --- /dev/null +++ b/headers/libs/ncurses/termcap.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * Copyright (c) 1998,2000 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE 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(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +/* $Id: termcap.h.in,v 1.16 2001/03/24 21:53:27 tom Exp $ */ + +#ifndef NCURSES_TERMCAP_H_incl +#define NCURSES_TERMCAP_H_incl 1 + +#undef NCURSES_VERSION +#define NCURSES_VERSION "5.5" + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include + +#undef NCURSES_CONST +#define NCURSES_CONST /*nothing*/ + +#undef NCURSES_OSPEED +#define NCURSES_OSPEED short + +extern NCURSES_EXPORT_VAR(char) PC; +extern NCURSES_EXPORT_VAR(char *) UP; +extern NCURSES_EXPORT_VAR(char *) BC; +extern NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed; + +#if !defined(NCURSES_TERM_H_incl) +extern NCURSES_EXPORT(char *) tgetstr (NCURSES_CONST char *, char **); +extern NCURSES_EXPORT(char *) tgoto (const char *, int, int); +extern NCURSES_EXPORT(int) tgetent (char *, const char *); +extern NCURSES_EXPORT(int) tgetflag (NCURSES_CONST char *); +extern NCURSES_EXPORT(int) tgetnum (NCURSES_CONST char *); +extern NCURSES_EXPORT(int) tputs (const char *, int, int (*)(int)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* NCURSES_TERMCAP_H_incl */ diff --git a/headers/libs/termcap/termcap.h b/headers/libs/termcap/termcap.h deleted file mode 100644 index b19fb0a17b..0000000000 --- a/headers/libs/termcap/termcap.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Declarations for termcap library. - Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _TERMCAP_H -#define _TERMCAP_H 1 - -#if __STDC__ - -extern int tgetent (char *buffer, const char *termtype); - -extern int tgetnum (const char *name); -extern int tgetflag (const char *name); -extern char *tgetstr (const char *name, char **area); - -extern char PC; -extern short ospeed; -extern void tputs (const char *string, int nlines, int (*outfun) (int)); - -extern char *tparam (const char *ctlstring, char *buffer, int size, ...); - -extern char *UP; -extern char *BC; - -extern char *tgoto (const char *cstring, int hpos, int vpos); - -#else /* not __STDC__ */ - -extern int tgetent (); - -extern int tgetnum (); -extern int tgetflag (); -extern char *tgetstr (); - -extern char PC; -extern short ospeed; - -extern void tputs (); - -extern char *tparam (); - -extern char *UP; -extern char *BC; - -extern char *tgoto (); - -#endif /* not __STDC__ */ - -#endif /* not _TERMCAP_H */ diff --git a/headers/os/drivers/PCI.h b/headers/os/drivers/PCI.h index ef0b50653c..1210349995 100644 --- a/headers/os/drivers/PCI.h +++ b/headers/os/drivers/PCI.h @@ -131,18 +131,18 @@ struct pci_module_info { pci_info *info /* caller-supplied buffer for info */ ); uint32 (*read_pci_config) ( - uchar bus, /* bus number */ - uchar device, /* device # on bus */ - uchar function, /* function # in device */ - uchar offset, /* offset in configuration space */ - uchar size /* # bytes to read (1, 2 or 4) */ + uint8 bus, /* bus number */ + uint8 device, /* device # on bus */ + uint8 function, /* function # in device */ + uint16 offset, /* offset in configuration space */ + uint8 size /* # bytes to read (1, 2 or 4) */ ); void (*write_pci_config) ( - uchar bus, /* bus number */ - uchar device, /* device # on bus */ - uchar function, /* function # in device */ - uchar offset, /* offset in configuration space */ - uchar size, /* # bytes to write (1, 2 or 4) */ + uint8 bus, /* bus number */ + uint8 device, /* device # on bus */ + uint8 function, /* function # in device */ + uint16 offset, /* offset in configuration space */ + uint8 size, /* # bytes to write (1, 2 or 4) */ uint32 value /* value to write */ ); @@ -174,6 +174,14 @@ struct pci_module_info { uchar device, uchar function, uchar newInterruptLineValue); + + status_t (*find_pci_extended_capability) ( + uint8 bus, + uint8 device, + uint8 function, + uint16 cap_id, + uint16 *offset + ); }; #define B_PCI_MODULE_NAME "bus_managers/pci/v1" @@ -196,6 +204,7 @@ struct pci_module_info { #define PCI_header_type 0x0e /* (1 byte) header type */ #define PCI_bist 0x0f /* (1 byte) built-in self-test */ +#define PCI_extended_capability 0x100 /* (4 bytes) extended capability */ /* --- @@ -690,6 +699,41 @@ struct pci_module_info { #define PCI_cap_id_sata 0x12 /* Serial ATA Capability */ #define PCI_cap_id_pciaf 0x13 /* PCI Advanced Features */ +/** PCI Extended Capabilities */ +#define PCI_extcap_id(x) (x & 0x0000ffff) +#define PCI_extcap_version(x) ((x & 0x000f0000) >> 16) +#define PCI_extcap_next_ptr(x) ((x & 0xfff00000) >> 20) + +#define PCI_extcap_id_aer 0x0001 /* Advanced Error Reporting */ +#define PCI_extcap_id_vc 0x0002 /* Virtual Channel */ +#define PCI_extcap_id_serial 0x0003 /* Serial Number */ +#define PCI_extcap_id_power_budget 0x0004 /* Power Budgeting */ +#define PCI_extcap_id_rcl_decl 0x0005 /* Root Complex Link Declaration */ +#define PCI_extcap_id_rcil_ctl 0x0006 /* Root Complex Internal Link Control */ +#define PCI_extcap_id_rcec_assoc 0x0007 /* Root Complex Event Collector Association */ +#define PCI_extcap_id_mfvc 0x0008 /* MultiFunction Virtual Channel */ +#define PCI_extcap_id_vc2 0x0009 /* Virtual Channel 2 */ +#define PCI_extcap_id_rcrb_header 0x000a /* RCRB Header */ +#define PCI_extcap_id_vendor 0x000b /* Vendor Unique */ +#define PCI_extcap_id_acs 0x000d /* Access Control Services */ +#define PCI_extcap_id_ari 0x000e /* Alternative Routing Id Interpretation */ +#define PCI_extcap_id_ats 0x000f /* Address Translation Services */ +#define PCI_extcap_id_srio_virtual 0x0010 /* Single Root I/O Virtualization */ +#define PCI_extcap_id_mrio_virtual 0x0011 /* Multiple Root I/O Virtual */ +#define PCI_extcap_id_multicast 0x0012 /* Multicast */ +#define PCI_extcap_id_page_request 0x0013 /* Page Request */ +#define PCI_extcap_id_amd 0x0014 /* AMD Reserved */ +#define PCI_extcap_id_resizable_bar 0x0015 /* Resizable Bar */ +#define PCI_extcap_id_dyn_power_alloc 0x0016 /* Dynamic Power Allocation */ +#define PCI_extcap_id_tph_requester 0x0017 /* TPH Requester */ +#define PCI_extcap_id_latency_tolerance 0x0018 /* Latency Tolerance Reporting */ +#define PCI_extcap_id_2ndpcie 0x0019 /* Secondary PCIe */ +#define PCI_extcap_id_pmux 0x001a /* Protocol Multiplexing */ +#define PCI_extcap_id_pasid 0x001b /* Process Address Space Id */ +#define PCI_extcap_id_ln_requester 0x001c /* LN Requester */ +#define PCI_extcap_id_dpc 0x001d /* Downstream Porto Containment */ +#define PCI_extcap_id_l1pm 0x001e /* L1 Power Management Substates */ + /** Power Management Control Status Register settings */ #define PCI_pm_mask 0x03 #define PCI_pm_ctrl 0x02 diff --git a/headers/os/drivers/bus/PCI.h b/headers/os/drivers/bus/PCI.h index fa362c7bc7..f0816d3361 100644 --- a/headers/os/drivers/bus/PCI.h +++ b/headers/os/drivers/bus/PCI.h @@ -27,13 +27,15 @@ typedef struct pci_device_module_info { void *(*ram_address)(pci_device *device, const void *physicalAddress); - uint32 (*read_pci_config)(pci_device *device, uint8 offset, + uint32 (*read_pci_config)(pci_device *device, uint16 offset, uint8 size); - void (*write_pci_config)(pci_device *device, uint8 offset, + void (*write_pci_config)(pci_device *device, uint16 offset, uint8 size, uint32 value); status_t (*find_pci_capability)(pci_device *device, uint8 capID, uint8 *offset); void (*get_pci_info)(pci_device *device, struct pci_info *info); + status_t (*find_pci_extended_capability)(pci_device *device, uint16 capID, + uint16 *offset); } pci_device_module_info; diff --git a/headers/os/drivers/bus/SCSI.h b/headers/os/drivers/bus/SCSI.h index fe088c2f82..ed4b616387 100644 --- a/headers/os/drivers/bus/SCSI.h +++ b/headers/os/drivers/bus/SCSI.h @@ -256,7 +256,7 @@ typedef struct { uint32 sim_priv; /* Size of SIM private data area */ uchar vuhba_flags[SCSI_VUHBA];/* Vendor unique capabilities */ uchar initiator_id; /* ID of the HBA on the SCSI bus */ - uint32 hba_queue_size; // size of adapaters command queue + uint32 hba_queue_size; // size of adapters command queue char sim_vid[SCSI_SIM_ID]; /* Vendor ID of the SIM */ char hba_vid[SCSI_HBA_ID]; /* Vendor ID of the HBA */ diff --git a/headers/os/interface/Box.h b/headers/os/interface/Box.h index d3e4009431..37bdf88d90 100644 --- a/headers/os/interface/Box.h +++ b/headers/os/interface/Box.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006, Haiku, Inc. All Rights Reserved. + * Copyright 2005-2013 Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _BOX_H @@ -11,7 +11,7 @@ class BBox : public BView { public: - BBox(BRect frame, const char *name = NULL, + BBox(BRect frame, const char* name = NULL, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS @@ -47,8 +47,8 @@ class BBox : public BView { virtual void DetachedFromWindow(); virtual void AllAttached(); virtual void AllDetached(); - virtual void FrameResized(float width, float height); - virtual void MessageReceived(BMessage* message); + virtual void FrameResized(float width, float height); + virtual void MessageReceived(BMessage* message); virtual void MouseDown(BPoint point); virtual void MouseUp(BPoint point); virtual void WindowActivated(bool active); @@ -56,20 +56,21 @@ class BBox : public BView { const BMessage* dragMessage); virtual void FrameMoved(BPoint newLocation); - virtual BHandler* ResolveSpecifier(BMessage* message, + virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier, int32 what, const char* property); - virtual void ResizeToPreferred(); - virtual void GetPreferredSize(float* _width, float* _height); - virtual void MakeFocus(bool focused = true); - virtual status_t GetSupportedSuites(BMessage* message); + virtual void ResizeToPreferred(); + virtual void GetPreferredSize(float* _width, float* _height); + virtual void MakeFocus(bool focused = true); + virtual status_t GetSupportedSuites(BMessage* message); - virtual status_t Perform(perform_code d, void* arg); + virtual status_t Perform(perform_code d, void* arg); virtual BSize MinSize(); virtual BSize MaxSize(); virtual BSize PreferredSize(); + virtual BAlignment LayoutAlignment(); protected: virtual void LayoutInvalidated(bool descendants = false); diff --git a/headers/os/interface/CheckBox.h b/headers/os/interface/CheckBox.h index b8d2c58ecc..7e7de4241f 100644 --- a/headers/os/interface/CheckBox.h +++ b/headers/os/interface/CheckBox.h @@ -17,9 +17,9 @@ public: uint32 flags = B_WILL_DRAW | B_NAVIGABLE); BCheckBox(const char* name, const char* label, BMessage* message, uint32 flags - = B_WILL_DRAW | B_NAVIGABLE); + = B_WILL_DRAW | B_NAVIGABLE); BCheckBox(const char* label, - BMessage* message = NULL); + BMessage* message = NULL); BCheckBox(BMessage* archive); virtual ~BCheckBox(); @@ -55,6 +55,7 @@ public: virtual BSize MinSize(); virtual BSize MaxSize(); virtual BSize PreferredSize(); + virtual BAlignment LayoutAlignment(); virtual void MakeFocus(bool focused = true); diff --git a/headers/os/interface/ColorControl.h b/headers/os/interface/ColorControl.h index 7c1437fd47..6875ee2506 100644 --- a/headers/os/interface/ColorControl.h +++ b/headers/os/interface/ColorControl.h @@ -1,5 +1,5 @@ /* - * Copyright 2005, Haiku, Inc. All Rights Reserved. + * Copyright 2005-2013 Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _COLOR_CONTROL_H @@ -8,8 +8,6 @@ #include -class BBitmap; - enum color_control_layout { B_CELLS_4x64 = 4, @@ -19,6 +17,8 @@ enum color_control_layout { B_CELLS_64x4 = 64, }; + +class BBitmap; class BTextControl; @@ -93,15 +93,19 @@ private: void _LayoutView(); void _InitOffscreen(); void _DrawColorArea(BView* target, BRect update); - void _DrawSelectors(BView* target); - void _ColorRamp(BRect rect, BView* target, - rgb_color baseColor, rgb_color compColor, - int16 flag, bool focused, BRect update); + void _DrawSelectors(BView* target); + void _DrawColorRamp(BRect rect, BView* target, + rgb_color baseColor, rgb_color compColor, + int16 flag, bool focused, + BRect updateRect); BPoint _SelectorPosition(const BRect& rampRect, uint8 shade) const; - BRect _PaletteSelectorFrame(uint8 colorIndex) const; + BRect _PaletteFrame() const; + BRect _PaletteSelectorFrame(uint8 colorIndex) const; BRect _RampFrame(uint8 rampIndex) const; - + void _SetCellSize(float size); + float _TextRectOffset(); + private: BRect fPaletteFrame; int16 fSelectedPaletteColorIndex; diff --git a/headers/os/interface/RadioButton.h b/headers/os/interface/RadioButton.h index 5586a51e97..48da0183bc 100644 --- a/headers/os/interface/RadioButton.h +++ b/headers/os/interface/RadioButton.h @@ -61,7 +61,7 @@ public: virtual status_t Perform(perform_code d, void* argument); virtual BSize MaxSize(); - + virtual BAlignment LayoutAlignment(); private: friend status_t _init_interface_kit_(); diff --git a/headers/os/interface/TextControl.h b/headers/os/interface/TextControl.h index aca56a18f9..77d36d9928 100644 --- a/headers/os/interface/TextControl.h +++ b/headers/os/interface/TextControl.h @@ -86,6 +86,7 @@ public: virtual BSize MinSize(); virtual BSize MaxSize(); virtual BSize PreferredSize(); + virtual BAlignment LayoutAlignment(); BLayoutItem* CreateLabelLayoutItem(); BLayoutItem* CreateTextViewLayoutItem(); diff --git a/headers/os/interface/View.h b/headers/os/interface/View.h index bac388e38f..39e1e6aaf0 100644 --- a/headers/os/interface/View.h +++ b/headers/os/interface/View.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2012, Haiku, Inc. All rights reserved. + * Copyright 2001-2013 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _VIEW_H @@ -196,22 +196,22 @@ public: BView* Parent() const; BRect Bounds() const; BRect Frame() const; - void ConvertToScreen(BPoint* pt) const; - BPoint ConvertToScreen(BPoint pt) const; - void ConvertFromScreen(BPoint* pt) const; - BPoint ConvertFromScreen(BPoint pt) const; - void ConvertToScreen(BRect* r) const; - BRect ConvertToScreen(BRect r) const; - void ConvertFromScreen(BRect* r) const; - BRect ConvertFromScreen(BRect r) const; - void ConvertToParent(BPoint* pt) const; - BPoint ConvertToParent(BPoint pt) const; - void ConvertFromParent(BPoint* pt) const; - BPoint ConvertFromParent(BPoint pt) const; - void ConvertToParent(BRect* r) const; - BRect ConvertToParent(BRect r) const; - void ConvertFromParent(BRect* r) const; - BRect ConvertFromParent(BRect r) const; + void ConvertToScreen(BPoint* point) const; + BPoint ConvertToScreen(BPoint point) const; + void ConvertFromScreen(BPoint* point) const; + BPoint ConvertFromScreen(BPoint point) const; + void ConvertToScreen(BRect* rect) const; + BRect ConvertToScreen(BRect rect) const; + void ConvertFromScreen(BRect* rect) const; + BRect ConvertFromScreen(BRect rect) const; + void ConvertToParent(BPoint* point) const; + BPoint ConvertToParent(BPoint point) const; + void ConvertFromParent(BPoint* point) const; + BPoint ConvertFromParent(BPoint point) const; + void ConvertToParent(BRect* rect) const; + BRect ConvertToParent(BRect rect) const; + void ConvertFromParent(BRect* rect) const; + BRect ConvertFromParent(BRect rect) const; BPoint LeftTop() const; void GetClippingRegion(BRegion* region) const; @@ -235,9 +235,9 @@ public: void SetViewCursor(const BCursor* cursor, bool sync = true); - virtual void SetViewColor(rgb_color c); - void SetViewColor(uchar r, uchar g, uchar b, - uchar a = 255); + virtual void SetViewColor(rgb_color color); + void SetViewColor(uchar red, uchar green, uchar blue, + uchar alpha = 255); rgb_color ViewColor() const; void SetViewBitmap(const BBitmap* bitmap, @@ -264,14 +264,14 @@ public: uint32 options = 0); void ClearViewOverlay(); - virtual void SetHighColor(rgb_color a_color); - void SetHighColor(uchar r, uchar g, uchar b, - uchar a = 255); + virtual void SetHighColor(rgb_color color); + void SetHighColor(uchar red, uchar green, uchar blue, + uchar alpha = 255); rgb_color HighColor() const; - virtual void SetLowColor(rgb_color a_color); - void SetLowColor(uchar r, uchar g, uchar b, - uchar a = 255); + virtual void SetLowColor(rgb_color color); + void SetLowColor(uchar red, uchar green, uchar blue, + uchar alpha = 255); rgb_color LowColor() const; void SetLineMode(cap_mode lineCap, @@ -292,110 +292,125 @@ public: void MovePenTo(float x, float y); void MovePenBy(float x, float y); BPoint PenLocation() const; - void StrokeLine(BPoint toPt, - pattern p = B_SOLID_HIGH); - void StrokeLine(BPoint a, BPoint b, - pattern p = B_SOLID_HIGH); + void StrokeLine(BPoint toPoint, + ::pattern pattern = B_SOLID_HIGH); + void StrokeLine(BPoint start, BPoint end, + ::pattern pattern = B_SOLID_HIGH); void BeginLineArray(int32 count); - void AddLine(BPoint a, BPoint b, rgb_color color); + void AddLine(BPoint start, BPoint end, + rgb_color color); void EndLineArray(); void StrokePolygon(const BPolygon* polygon, bool closed = true, - pattern p = B_SOLID_HIGH); - void StrokePolygon(const BPoint* ptArray, - int32 numPts, bool closed = true, - pattern p = B_SOLID_HIGH); - void StrokePolygon(const BPoint* ptArray, - int32 numPts, BRect bounds, + ::pattern pattern = B_SOLID_HIGH); + void StrokePolygon(const BPoint* pointArray, + int32 numPoints, bool closed = true, + ::pattern pattern = B_SOLID_HIGH); + void StrokePolygon(const BPoint* pointArray, + int32 numPoints, BRect bounds, bool closed = true, - pattern p = B_SOLID_HIGH); + ::pattern pattern = B_SOLID_HIGH); void FillPolygon(const BPolygon* polygon, - pattern p = B_SOLID_HIGH); - void FillPolygon(const BPoint* ptArray, - int32 numPts, pattern p = B_SOLID_HIGH); - void FillPolygon(const BPoint* ptArray, - int32 numPts, BRect bounds, - pattern p = B_SOLID_HIGH); + ::pattern pattern = B_SOLID_HIGH); + void FillPolygon(const BPoint* pointArray, + int32 numPoints, + ::pattern pattern = B_SOLID_HIGH); + void FillPolygon(const BPoint* pointArray, + int32 numPoints, BRect bounds, + ::pattern pattern = B_SOLID_HIGH); void FillPolygon(const BPolygon* polygon, const BGradient& gradient); - void FillPolygon(const BPoint* ptArray, - int32 numPts, const BGradient& gradient); - void FillPolygon(const BPoint* ptArray, - int32 numPts, BRect bounds, + void FillPolygon(const BPoint* pointArray, + int32 numPoints, const BGradient& gradient); + void FillPolygon(const BPoint* pointArray, + int32 numPoints, BRect bounds, const BGradient& gradient); - void StrokeTriangle(BPoint pt1, BPoint pt2, - BPoint pt3, BRect bounds, - pattern p = B_SOLID_HIGH); - void StrokeTriangle(BPoint pt1, BPoint pt2, - BPoint pt3, pattern p = B_SOLID_HIGH); - void FillTriangle(BPoint pt1, BPoint pt2, - BPoint pt3, pattern p = B_SOLID_HIGH); - void FillTriangle(BPoint pt1, BPoint pt2, - BPoint pt3, BRect bounds, - pattern p = B_SOLID_HIGH); - void FillTriangle(BPoint pt1, BPoint pt2, - BPoint pt3, const BGradient& gradient); - void FillTriangle(BPoint pt1, BPoint pt2, - BPoint pt3, BRect bounds, + void StrokeTriangle(BPoint point1, BPoint point2, + BPoint point3, BRect bounds, + ::pattern pattern = B_SOLID_HIGH); + void StrokeTriangle(BPoint point1, BPoint point2, + BPoint point3, + ::pattern pattern = B_SOLID_HIGH); + void FillTriangle(BPoint point1, BPoint point2, + BPoint point3, + ::pattern pattern = B_SOLID_HIGH); + void FillTriangle(BPoint point1, BPoint point2, + BPoint point3, BRect bounds, + ::pattern pattern = B_SOLID_HIGH); + void FillTriangle(BPoint point1, BPoint point2, + BPoint point3, const BGradient& gradient); + void FillTriangle(BPoint point1, BPoint point2, + BPoint point3, BRect bounds, const BGradient& gradient); - void StrokeRect(BRect r, pattern p = B_SOLID_HIGH); - void FillRect(BRect r, pattern p = B_SOLID_HIGH); - void FillRect(BRect r, const BGradient& gradient); - void FillRegion(BRegion* region, - pattern p = B_SOLID_HIGH); - void FillRegion(BRegion* region, + void StrokeRect(BRect rect, + ::pattern pattern = B_SOLID_HIGH); + void FillRect(BRect rect, + ::pattern pattern = B_SOLID_HIGH); + void FillRect(BRect rect, const BGradient& gradient); + void FillRegion(BRegion* rectegion, + ::pattern pattern = B_SOLID_HIGH); + void FillRegion(BRegion* rectegion, const BGradient& gradient); - void InvertRect(BRect r); + void InvertRect(BRect rect); - void StrokeRoundRect(BRect r, float xRadius, - float yRadius, pattern p = B_SOLID_HIGH); - void FillRoundRect(BRect r, float xRadius, - float yRadius, pattern p = B_SOLID_HIGH); - void FillRoundRect(BRect r, float xRadius, + void StrokeRoundRect(BRect rect, float xRadius, + float yRadius, + ::pattern pattern = B_SOLID_HIGH); + void FillRoundRect(BRect rect, float xRadius, + float yRadius, + ::pattern pattern = B_SOLID_HIGH); + void FillRoundRect(BRect rect, float xRadius, float yRadius, const BGradient& gradient); void StrokeEllipse(BPoint center, float xRadius, - float yRadius, pattern p = B_SOLID_HIGH); - void StrokeEllipse(BRect r, - pattern p = B_SOLID_HIGH); + float yRadius, + ::pattern pattern = B_SOLID_HIGH); + void StrokeEllipse(BRect rect, + ::pattern pattern = B_SOLID_HIGH); void FillEllipse(BPoint center, float xRadius, - float yRadius, pattern p = B_SOLID_HIGH); - void FillEllipse(BRect r, pattern p = B_SOLID_HIGH); + float yRadius, + ::pattern pattern = B_SOLID_HIGH); + void FillEllipse(BRect rect, + ::pattern pattern = B_SOLID_HIGH); void FillEllipse(BPoint center, float xRadius, float yRadius, const BGradient& gradient); - void FillEllipse(BRect r, + void FillEllipse(BRect rect, const BGradient& gradient); void StrokeArc(BPoint center, float xRadius, float yRadius, float startAngle, - float arcAngle, pattern p = B_SOLID_HIGH); - void StrokeArc(BRect r, float startAngle, - float arcAngle, pattern p = B_SOLID_HIGH); + float arcAngle, + ::pattern pattern = B_SOLID_HIGH); + void StrokeArc(BRect rect, float startAngle, + float arcAngle, + ::pattern pattern = B_SOLID_HIGH); void FillArc(BPoint center, float xRadius, float yRadius, float startAngle, - float arcAngle, pattern p = B_SOLID_HIGH); - void FillArc(BRect r, float startAngle, - float arcAngle, pattern p = B_SOLID_HIGH); + float arcAngle, + ::pattern pattern = B_SOLID_HIGH); + void FillArc(BRect rect, float startAngle, + float arcAngle, + ::pattern pattern = B_SOLID_HIGH); void FillArc(BPoint center, float xRadius, float yRadius, float startAngle, float arcAngle, const BGradient& gradient); - void FillArc(BRect r, float startAngle, + void FillArc(BRect rect, float startAngle, float arcAngle, const BGradient& gradient); void StrokeBezier(BPoint* controlPoints, - pattern p = B_SOLID_HIGH); + ::pattern pattern = B_SOLID_HIGH); void FillBezier(BPoint* controlPoints, - pattern p = B_SOLID_HIGH); + ::pattern pattern = B_SOLID_HIGH); void FillBezier(BPoint* controlPoints, const BGradient& gradient); void StrokeShape(BShape* shape, - pattern p = B_SOLID_HIGH); + ::pattern pattern = B_SOLID_HIGH); void FillShape(BShape* shape, - pattern p = B_SOLID_HIGH); + ::pattern pattern = B_SOLID_HIGH); void FillShape(BShape* shape, const BGradient& gradient); @@ -442,7 +457,7 @@ public: const BPoint* locations, int32 locationCount); - virtual void SetFont(const BFont* font, + virtual void SetFont(const BFont* font, uint32 mask = B_FONT_ALL); void GetFont(BFont* font) const; @@ -508,22 +523,22 @@ public: void Flush() const; void Sync() const; - virtual void GetPreferredSize(float* width, float* height); + virtual void GetPreferredSize(float* _width, float* _height); virtual void ResizeToPreferred(); BScrollBar* ScrollBar(orientation posture) const; - virtual BHandler* ResolveSpecifier(BMessage* msg, int32 index, + virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier, int32 form, const char* property); - virtual status_t GetSupportedSuites(BMessage* data); + virtual status_t GetSupportedSuites(BMessage* data); bool IsPrinting() const; void SetScale(float scale) const; float Scale() const; // new for Haiku - virtual status_t Perform(perform_code code, void* data); + virtual status_t Perform(perform_code code, void* data); virtual void DrawAfterChildren(BRect r); @@ -581,7 +596,7 @@ public: void HideToolTip(); protected: - virtual bool GetToolTipAt(BPoint point, BToolTip** _tip); + virtual bool GetToolTipAt(BPoint point, BToolTip** _tip); virtual void LayoutChanged(); @@ -720,37 +735,37 @@ BView::ScrollTo(float x, float y) inline void -BView::SetViewColor(uchar r, uchar g, uchar b, uchar a) +BView::SetViewColor(uchar red, uchar green, uchar blue, uchar alpha) { rgb_color color; - color.red = r; - color.green = g; - color.blue = b; - color.alpha = a; + color.red = red; + color.green = green; + color.blue = blue; + color.alpha = alpha; SetViewColor(color); } inline void -BView::SetHighColor(uchar r, uchar g, uchar b, uchar a) +BView::SetHighColor(uchar red, uchar green, uchar blue, uchar alpha) { rgb_color color; - color.red = r; - color.green = g; - color.blue = b; - color.alpha = a; + color.red = red; + color.green = green; + color.blue = blue; + color.alpha = alpha; SetHighColor(color); } inline void -BView::SetLowColor(uchar r, uchar g, uchar b, uchar a) +BView::SetLowColor(uchar red, uchar green, uchar blue, uchar alpha) { rgb_color color; - color.red = r; - color.green = g; - color.blue = b; - color.alpha = a; + color.red = red; + color.green = green; + color.blue = blue; + color.alpha = alpha; SetLowColor(color); } diff --git a/headers/os/kernel/OS.h b/headers/os/kernel/OS.h index dc91207136..1b2e7f8849 100644 --- a/headers/os/kernel/OS.h +++ b/headers/os/kernel/OS.h @@ -85,6 +85,11 @@ typedef struct area_info { /* area protection */ #define B_READ_AREA 1 #define B_WRITE_AREA 2 +#define B_EXECUTE_AREA 4 +#define B_STACK_AREA 8 + // "stack" protection is not available on most platforms - it's used + // to only commit memory as needed, and have guard pages at the + // bottom of the stack. extern area_id create_area(const char *name, void **startAddress, uint32 addressSpec, size_t size, uint32 lock, diff --git a/headers/os/kernel/debugger.h b/headers/os/kernel/debugger.h index c443b3977a..770d0b7c00 100644 --- a/headers/os/kernel/debugger.h +++ b/headers/os/kernel/debugger.h @@ -487,7 +487,7 @@ typedef struct { typedef struct { debug_origin origin; uint32 syscall; // the syscall number - uint32 args[16]; // syscall arguments + uint8 args[128]; // syscall arguments } debug_pre_syscall; // B_DEBUGGER_MESSAGE_POST_SYSCALL @@ -498,7 +498,7 @@ typedef struct { bigtime_t end_time; // time of syscall completion uint64 return_value; // the syscall's return value uint32 syscall; // the syscall number - uint32 args[16]; // syscall arguments + uint8 args[128]; // syscall arguments } debug_post_syscall; // B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED diff --git a/headers/private/graphics/intel_extreme/AreaKeeper.h b/headers/private/graphics/intel_extreme/AreaKeeper.h index d604bb45cb..83861397f2 100644 --- a/headers/private/graphics/intel_extreme/AreaKeeper.h +++ b/headers/private/graphics/intel_extreme/AreaKeeper.h @@ -22,8 +22,9 @@ class AreaKeeper { area_id Create(const char *name, void **_virtualAddress, uint32 spec, size_t size, uint32 lock, uint32 protection); - area_id Map(const char *name, addr_t physicalAddress, size_t numBytes, - uint32 spec, uint32 protection, void **_virtualAddress); + area_id Map(const char *name, phys_addr_t physicalAddress, + size_t numBytes, uint32 spec, uint32 protection, + void **_virtualAddress); status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; } void Detach(); @@ -57,7 +58,7 @@ AreaKeeper::Create(const char *name, void **_virtualAddress, uint32 spec, area_id -AreaKeeper::Map(const char *name, addr_t physicalAddress, size_t numBytes, +AreaKeeper::Map(const char *name, phys_addr_t physicalAddress, size_t numBytes, uint32 spec, uint32 protection, void **_virtualAddress) { fArea = map_physical_memory(name, physicalAddress, numBytes, spec, diff --git a/headers/private/graphics/radeon_hd/radeon_hd.h b/headers/private/graphics/radeon_hd/radeon_hd.h index 6ae08f929d..7025ddf8cf 100644 --- a/headers/private/graphics/radeon_hd/radeon_hd.h +++ b/headers/private/graphics/radeon_hd/radeon_hd.h @@ -32,10 +32,11 @@ // Card chipset flags #define CHIP_STD (1 << 0) // Standard chipset -#define CHIP_IGP (1 << 1) // IGP chipset -#define CHIP_MOBILE (1 << 2) // Mobile chipset -#define CHIP_DISCREET (1 << 3) // Discreet chipset -#define CHIP_APU (1 << 4) // APU chipset +#define CHIP_X2 (1 << 1) // Dual cpu +#define CHIP_IGP (1 << 2) // IGP chipset +#define CHIP_MOBILE (1 << 3) // Mobile chipset +#define CHIP_DISCREET (1 << 4) // Discreet chipset +#define CHIP_APU (1 << 5) // APU chipset #define DEVICE_NAME "radeon_hd" #define RADEON_ACCELERANT_NAME "radeon_hd.accelerant" @@ -86,16 +87,18 @@ enum radeon_chipset { RADEON_PALM, //Fusion APU (NI), Radeon HD 6000 RADEON_SUMO, RADEON_SUMO2, - RADEON_CAICOS, //Nothern Islands, Radeon HD 6000 + RADEON_CAICOS, //Nothern Islands, Radeon HD 6000 / Low end 7000 RADEON_TURKS, RADEON_BARTS, RADEON_CAYMAN, RADEON_ANTILLES, - RADEON_LOMBOK, //Southern Islands, Radeon HD 7000 - RADEON_CAPEVERDE, + RADEON_CAPEVERDE, //Southern Islands, Radeon HD 7000 aka ARUBA + RADEON_BONAIRE, RADEON_PITCAIRN, RADEON_TAHITI, - RADEON_NEWZEALAND + RADEON_OLAND, //Sea Islands, Radeon HD 8000 + RADEON_HAINAN, // NO DCE? + RADEON_CURACAO, }; diff --git a/headers/private/interface/BMCPrivate.h b/headers/private/interface/BMCPrivate.h index 5c9678c388..876ad1f37c 100644 --- a/headers/private/interface/BMCPrivate.h +++ b/headers/private/interface/BMCPrivate.h @@ -16,6 +16,9 @@ #include +static const float kVMargin = 2.0f; + + class BMessageRunner; @@ -48,6 +51,7 @@ public: virtual void FrameResized(float width, float height); virtual void MessageReceived(BMessage* msg); virtual void MakeFocus(bool focused = true); + virtual void SetMaxContentWidth(float width); void TogglePopUpMarker(bool show) { fShowPopUpMarker = show; } @@ -60,7 +64,7 @@ public: private: _BMCMenuBar_&operator=(const _BMCMenuBar_&); - void _Init(bool setMaxContentWidth); + void _Init(); BMenuField* fMenuField; bool fFixedSize; diff --git a/headers/private/libroot/libroot_private.h b/headers/private/libroot/libroot_private.h index 593ffd3526..85bc14d11f 100644 --- a/headers/private/libroot/libroot_private.h +++ b/headers/private/libroot/libroot_private.h @@ -18,6 +18,8 @@ struct real_time_data; extern "C" { #endif +extern int __gABIVersion; + extern char _single_threaded; /* This determines if a process runs single threaded or not */ @@ -31,7 +33,7 @@ status_t __flatten_process_args(const char* const* args, int32 argCount, size_t* _flatSize); void _call_atexit_hooks_for_range(addr_t start, addr_t size); void __init_env(const struct user_space_program_args *args); -void __init_heap(void); +status_t __init_heap(void); void __init_heap_post_env(void); void __init_time(addr_t commPageTable); @@ -42,6 +44,8 @@ void __init_pwd_backend(void); void __reinit_pwd_backend_after_fork(void); void* __arch_get_caller(void); +void __set_stack_protection(void); + #ifdef __cplusplus } diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index 39e675f8a9..4d328414e2 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -52,6 +52,7 @@ struct rld_export { const struct user_space_program_args *program_args; const void* commpage_address; + int abi_version; }; extern struct rld_export *__gRuntimeLoader; diff --git a/headers/private/shared/RegExp.h b/headers/private/shared/RegExp.h new file mode 100644 index 0000000000..0214977848 --- /dev/null +++ b/headers/private/shared/RegExp.h @@ -0,0 +1,80 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef REG_EXP_H +#define REG_EXP_H + + +#include + + +class RegExp { +public: + enum PatternType { + PATTERN_TYPE_REGULAR_EXPRESSION, + PATTERN_TYPE_WILDCARD + }; + + class MatchResult; + +public: + RegExp(); + RegExp(const char* pattern, + PatternType patternType + = PATTERN_TYPE_REGULAR_EXPRESSION, + bool caseSensitive = true); + RegExp(const RegExp& other); + ~RegExp(); + + bool IsValid() const + { return fData != NULL; } + + bool SetPattern(const char* pattern, + PatternType patternType + = PATTERN_TYPE_REGULAR_EXPRESSION, + bool caseSensitive = true); + + MatchResult Match(const char* string) const; + + RegExp& operator=(const RegExp& other); + +private: + struct Data; + struct MatchResultData; + +private: + Data* fData; +}; + + +class RegExp::MatchResult { +public: + MatchResult(); + MatchResult(const MatchResult& other); + ~MatchResult(); + + bool HasMatched() const; + + size_t StartOffset() const; + size_t EndOffset() const; + + size_t GroupCount() const; + size_t GroupStartOffsetAt(size_t index) const; + size_t GroupEndOffsetAt(size_t index) const; + + MatchResult& operator=(const MatchResult& other); + +private: + friend class RegExp; + +private: + MatchResult(MatchResultData* data); + // takes over the data reference + +private: + MatchResultData* fData; +}; + + +#endif // REG_EXP_H diff --git a/headers/private/system/vm_defs.h b/headers/private/system/vm_defs.h index 53643a9082..c5f405014b 100644 --- a/headers/private/system/vm_defs.h +++ b/headers/private/system/vm_defs.h @@ -15,13 +15,6 @@ // Note: the VM probably won't support all combinations - it will try // its best, but create_area() will fail if it has to. // Of course, the exact behaviour will be documented somewhere... -#define B_EXECUTE_AREA 0x04 -#define B_STACK_AREA 0x08 - // "stack" protection is not available on most platforms - it's used - // to only commit memory as needed, and have guard pages at the - // bottom of the stack. - // "execute" protection is currently ignored, but nevertheless, you - // should use it if you require to execute code in that area. #define B_KERNEL_EXECUTE_AREA 0x40 #define B_KERNEL_STACK_AREA 0x80 diff --git a/headers/private/virtio/virtio.h b/headers/private/virtio/virtio.h new file mode 100644 index 0000000000..3b2b299539 --- /dev/null +++ b/headers/private/virtio/virtio.h @@ -0,0 +1,123 @@ +/* + * Copyright 2013, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _VIRTIO_H_ +#define _VIRTIO_H_ + + +#include +#include + + +#define VIRTIO_DEVICE_ID_NETWORK 0x01 +#define VIRTIO_DEVICE_ID_BLOCK 0x02 +#define VIRTIO_DEVICE_ID_CONSOLE 0x03 +#define VIRTIO_DEVICE_ID_ENTROPY 0x04 +#define VIRTIO_DEVICE_ID_BALLOON 0x05 +#define VIRTIO_DEVICE_ID_IOMEMORY 0x06 +#define VIRTIO_DEVICE_ID_RP_MESSAGE 0x07 +#define VIRTIO_DEVICE_ID_SCSI 0x08 +#define VIRTIO_DEVICE_ID_9P 0x09 +#define VIRTIO_DEVICE_ID_RP_SERIAL 0x0b +#define VIRTIO_DEVICE_ID_CAIF 0x0c + +#define VIRTIO_FEATURE_TRANSPORT_MASK ((1 << 28) - 1) + +#define VIRTIO_FEATURE_NOTIFY_ON_EMPTY (1 << 24) +#define VIRTIO_FEATURE_RING_INDIRECT_DESC (1 << 28) +#define VIRTIO_FEATURE_RING_EVENT_IDX (1 << 29) +#define VIRTIO_FEATURE_BAD_FEATURE (1 << 30) + +#define VIRTIO_VIRTQUEUES_MAX_COUNT 8 + +#define VIRTIO_CONFIG_STATUS_RESET 0x00 +#define VIRTIO_CONFIG_STATUS_ACK 0x01 +#define VIRTIO_CONFIG_STATUS_DRIVER 0x02 +#define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04 +#define VIRTIO_CONFIG_STATUS_FAILED 0x80 + +// attributes: + +// node type +#define VIRTIO_BUS_TYPE_NAME "bus/virtio/v1" +// device type (uint16) +#define VIRTIO_DEVICE_TYPE_ITEM "virtio/type" +// alignment (uint16) +#define VIRTIO_VRING_ALIGNMENT_ITEM "virtio/vring_alignment" + +// sim cookie, issued by virtio bus manager +typedef void* virtio_sim; +// device cookie, issued by virtio bus manager +typedef void* virtio_device; +// queue cookie, issued by virtio bus manager +typedef void* virtio_queue; +// callback function for requests +typedef void (*virtio_callback_func)(void *cookie); +// callback function for interrupts +typedef void (*virtio_intr_func)(void *cookie); + +#define VIRTIO_DEVICE_MODULE_NAME "bus_managers/virtio/device/v1" + +typedef struct { + driver_module_info info; + + status_t (*queue_interrupt_handler)(virtio_sim sim, uint16 queue); + status_t (*config_interrupt_handler)(virtio_sim sim); +} virtio_for_controller_interface; + +#define VIRTIO_FOR_CONTROLLER_MODULE_NAME "bus_managers/virtio/controller/driver_v1" + +// Bus manager interface used by Virtio controller drivers. +typedef struct { + driver_module_info info; + + void (*set_sim)(void* cookie, virtio_sim sim); + status_t (*read_host_features)(void* cookie, uint32* features); + status_t (*write_guest_features)(void* cookie, uint32 features); + uint8 (*get_status)(void* cookie); + void (*set_status)(void* cookie, uint8 status); + status_t (*read_device_config)(void* cookie, uint8 offset, void* buffer, + size_t bufferSize); + status_t (*write_device_config)(void* cookie, uint8 offset, + const void* buffer, size_t bufferSize); + + uint16 (*get_queue_ring_size)(void* cookie, uint16 queue); + status_t (*setup_queue)(void* cookie, uint16 queue, phys_addr_t phy); + status_t (*setup_interrupt)(void* cookie); + void (*notify_queue)(void* cookie, uint16 queue); +} virtio_sim_interface; + + +// bus manager device interface for peripheral driver +typedef struct { + driver_module_info info; + + status_t (*negociate_features)(virtio_device cookie, uint32 supported, + uint32* negociated, const char* (*get_feature_name)(uint32)); + + status_t (*read_device_config)(virtio_device cookie, uint8 offset, + void* buffer, size_t bufferSize); + status_t (*write_device_config)(virtio_device cookie, uint8 offset, + const void* buffer, size_t bufferSize); + + status_t (*alloc_queues)(virtio_device cookie, size_t count, + virtio_queue *queues); + + status_t (*setup_interrupt)(virtio_device cookie, + virtio_intr_func config_handler, void* configCookie); + + status_t (*queue_request)(virtio_queue queue, + const physical_entry *readEntry, + const physical_entry *writtenEntry, virtio_callback_func callback, + void *callbackCookie); + + status_t (*queue_request_v)(virtio_queue queue, + const physical_entry* vector, + size_t readVectorCount, size_t writtenVectorCount, + virtio_callback_func callback, void *callbackCookie); + +} virtio_device_interface; + + +#endif /* _VIRTIO_H_ */ diff --git a/src/add-ons/accelerants/radeon_hd/atombios/atombios.h b/src/add-ons/accelerants/radeon_hd/atombios/atombios.h index 634780a38d..c9c11af80f 100644 --- a/src/add-ons/accelerants/radeon_hd/atombios/atombios.h +++ b/src/add-ons/accelerants/radeon_hd/atombios/atombios.h @@ -459,6 +459,7 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 union { ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter + ULONG ulClockParams; //ULONG access for BE ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter }; UCHAR ucRefDiv; //Output Parameter @@ -491,6 +492,7 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 union { ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter + ULONG ulClockParams; //ULONG access for BE ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter }; UCHAR ucRefDiv; //Output Parameter diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index 321275c8ac..3a2238c005 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -270,12 +270,13 @@ detect_displays() edid1_info* edid = &gDisplay[displayIndex]->edidData; gDisplay[displayIndex]->attached = ddc2_dp_read_edid1(id, edid); - + if (gDisplay[displayIndex]->attached) { TRACE("%s: connector(%" B_PRIu32 "): Found DisplayPort EDID!\n", __func__); } } + // TODO: Handle external DP brides - ?? #if 0 if (gConnector[id]->encoderExternal.isDPBridge == true) { @@ -289,14 +290,26 @@ detect_displays() // TODO: DDC Router switching for DisplayPort (and others?) } #endif + if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) { - // If plain (non-DP) laptop LVDS, read mode info from AtomBIOS - //TRACE("%s: non-DP laptop LVDS detected\n", __func__); - gDisplay[displayIndex]->attached = connector_read_mode_lvds(id, - &gDisplay[displayIndex]->preferredMode); - if (gDisplay[displayIndex]->attached) { - TRACE("%s: connector(%" B_PRIu32 "): found LVDS preferred " - "mode\n", __func__, id); + display_mode preferredMode; + bool lvdsInfoFound = connector_read_mode_lvds(id, + &preferredMode); + TRACE("%s: connector(%" B_PRIu32 "): bit-banging LVDS for EDID.\n", + __func__, id); + + gDisplay[displayIndex]->attached = connector_read_edid(id, + &gDisplay[displayIndex]->edidData); + + if (!gDisplay[displayIndex]->attached && lvdsInfoFound) { + // If we didn't find ddc edid data, fallback to lvdsInfo + // We have to call connector_read_mode_lvds first to + // collect SS data for the lvds connector + TRACE("%s: connector(%" B_PRIu32 "): using AtomBIOS LVDS_Info " + "preferred mode\n", __func__, id); + gDisplay[displayIndex]->attached = true; + memcpy(&gDisplay[displayIndex]->preferredMode, + &preferredMode, sizeof(display_mode)); } } @@ -305,9 +318,9 @@ detect_displays() TRACE("%s: connector(%" B_PRIu32 "): bit-banging ddc for EDID.\n", __func__, id); - // Lets try bit-banging edid from connector - gDisplay[displayIndex]->attached - = connector_read_edid(id, &gDisplay[displayIndex]->edidData); + // Bit-bang edid from connector + gDisplay[displayIndex]->attached = connector_read_edid(id, + &gDisplay[displayIndex]->edidData); // Found EDID data? if (gDisplay[displayIndex]->attached) { diff --git a/src/add-ons/input_server/filters/shortcut_catcher/KeyInfos.cpp b/src/add-ons/input_server/filters/shortcut_catcher/KeyInfos.cpp index 5174b4fb59..0014e315e8 100644 --- a/src/add-ons/input_server/filters/shortcut_catcher/KeyInfos.cpp +++ b/src/add-ons/input_server/filters/shortcut_catcher/KeyInfos.cpp @@ -19,7 +19,7 @@ #include -#define NUM_KEYS 256 +#define NUM_KEYS 128 #define MAX_UTF8_LENGTH 5 // up to 4 chars, plus a nul terminator struct KeyLabelMap { @@ -97,10 +97,8 @@ static const char* keyDescriptions[NUM_KEYS]; // series of optional up-to-(4+1)-byte terminated UTF-8 character strings... static char utfDescriptions[NUM_KEYS * MAX_UTF8_LENGTH]; -static const char* FindSpecialKeyLabelFor(uint8 keyCode, int& last); - static const char* -FindSpecialKeyLabelFor(uint8 keyCode, int& last) +FindSpecialKeyLabelFor(uint8 keyCode, uint32& last) { while ((keyLabels[last].fKeyCode < keyCode) && (last < (sizeof(keyLabels) / sizeof(struct KeyLabelMap)) - 1)) @@ -116,7 +114,7 @@ FindSpecialKeyLabelFor(uint8 keyCode, int& last) void InitKeyIndices() { - int nextSpecial = 0; + uint32 nextSpecial = 0; key_map* map; char* keys; get_key_map(&map, &keys); @@ -125,8 +123,8 @@ InitKeyIndices() keyDescriptions[j] = NULL; // default const char* slabel = FindSpecialKeyLabelFor(j, nextSpecial); - int keyCode = map->normal_map[j]; - + int32 keyCode = map->normal_map[j]; + if (keyCode >= 0) { const char* mapDesc = &keys[keyCode]; uint8 len = *mapDesc; diff --git a/src/add-ons/kernel/bus_managers/Jamfile b/src/add-ons/kernel/bus_managers/Jamfile index 319c6317a4..f1de07bb5b 100644 --- a/src/add-ons/kernel/bus_managers/Jamfile +++ b/src/add-ons/kernel/bus_managers/Jamfile @@ -12,3 +12,4 @@ SubInclude HAIKU_TOP src add-ons kernel bus_managers ps2 ; SubInclude HAIKU_TOP src add-ons kernel bus_managers scsi ; SubInclude HAIKU_TOP src add-ons kernel bus_managers tty ; SubInclude HAIKU_TOP src add-ons kernel bus_managers usb ; +SubInclude HAIKU_TOP src add-ons kernel bus_managers virtio ; diff --git a/src/add-ons/kernel/bus_managers/acpi/NamespaceDump.cpp b/src/add-ons/kernel/bus_managers/acpi/NamespaceDump.cpp index 3502fd4a84..b71ce4893b 100644 --- a/src/add-ons/kernel/bus_managers/acpi/NamespaceDump.cpp +++ b/src/add-ons/kernel/bus_managers/acpi/NamespaceDump.cpp @@ -1,19 +1,25 @@ -/* ++++++++++ - ACPI namespace dump. - Nothing special here, just tree enumeration and type identification. -+++++ */ +/* + * Copyright 2006-2013, Jérôme Duval. All rights reserved. + * Copyright 2011-2012, Fredrik Holmqvis. All rights reserved. + * Copyright 2008, Stefano Ceccherini. All rights reserved. + * Copyright 2006, Bryan Varner. All rights reserved. + * Distributed under the terms of the MIT License. + */ + -#include -#include #include #include #include +#include -#include "ACPIPrivate.h" +#include #include #include +#include "ACPIPrivate.h" + + class RingBuffer { public: RingBuffer(size_t size = 1024); @@ -166,7 +172,7 @@ static int32 acpi_namespace_dump(void *arg) { acpi_ns_device_info *device = (acpi_ns_device_info*)(arg); - dump_acpi_namespace(device, NULL, 0); + dump_acpi_namespace(device, NULL, 0); delete_sem(device->read_sem); device->read_sem = -1; @@ -231,7 +237,7 @@ acpi_namespace_read(void *_cookie, off_t position, void *buf, size_t* num_bytes) if (ringBuffer.ReadableAmount() == 0) { ringBuffer.Unlock(); status_t status = acquire_sem_etc(device->read_sem, 1, B_CAN_INTERRUPT, 0); - if (status != B_OK) { + if (status != B_OK && status != B_BAD_SEM_ID) { *num_bytes = 0; return status; } @@ -279,17 +285,7 @@ acpi_namespace_control(void* cookie, uint32 op, void* arg, size_t len) static status_t acpi_namespace_close(void* cookie) { - status_t status; - acpi_ns_device_info *device = (acpi_ns_device_info *)cookie; dprintf("acpi_ns_dump: device_close\n"); - - if (device->read_sem >= 0) - delete_sem(device->read_sem); - - device->buffer->DestroyLock(); - wait_for_thread(device->thread, &status); - delete device->buffer; - return B_OK; } @@ -301,8 +297,17 @@ acpi_namespace_close(void* cookie) static status_t acpi_namespace_free(void* cookie) { + status_t status; + acpi_ns_device_info *device = (acpi_ns_device_info *)cookie; dprintf("acpi_ns_dump: device_free\n"); + if (device->read_sem >= 0) + delete_sem(device->read_sem); + + device->buffer->DestroyLock(); + wait_for_thread(device->thread, &status); + delete device->buffer; + return B_OK; } diff --git a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp index d29f51c53e..c81474a82d 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/m68k/atari/pci_atari.cpp @@ -82,9 +82,9 @@ static int m68k_atari_enable_config(struct m68k_atari_fake_host_bridge *bridge, uint8 bus, uint8 slot, uint8 function, uint8 offset); static status_t m68k_atari_read_pci_config(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 offset, uint8 size, uint32 *value); + uint8 function, uint16 offset, uint8 size, uint32 *value); static status_t m68k_atari_write_pci_config(void *cookie, uint8 bus, - uint8 device, uint8 function, uint8 offset, uint8 size, + uint8 device, uint8 function, uint16 offset, uint8 size, uint32 value); static status_t m68k_atari_get_max_bus_devices(void *cookie, int32 *count); static status_t m68k_atari_read_pci_irq(void *cookie, uint8 bus, uint8 device, @@ -103,7 +103,7 @@ static pci_controller sM68kAtariPCIController = { static status_t m68k_atari_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value) + uint16 offset, uint8 size, uint32 *value) { struct fake_pci_device *devices = (struct fake_pci_device *)cookie; struct fake_pci_device *dev; @@ -183,7 +183,7 @@ m68k_atari_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function static status_t m68k_atari_write_pci_config(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 offset, uint8 size, uint32 value) + uint8 function, uint16 offset, uint8 size, uint32 value) { #if 0 if (m68k_atari_enable_config(bridge, bus, device, function, offset)) { diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/grackle.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/grackle.cpp index 7a67ca02c4..b0a98f16d8 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/grackle.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/grackle.cpp @@ -80,13 +80,16 @@ struct grackle_host_bridge { static status_t grackle_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value) + uint16 offset, uint8 size, uint32 *value) { grackle_host_bridge *bridge = (grackle_host_bridge*)cookie; TRACE("grackle_read_pci_config(bus=%u, dev=%u, func=%u, offset=%u, " "size=%u)\n", (int)bus, (int)device, (int)function, (int)offset, (int)size); + if (offset > 0xff) + return B_BAD_VALUE; + out32rb(bridge->address_registers, (1 << 31) | (bus << 16) | ((device & 0x1f) << 11) | ((function & 0x7) << 8) | (offset & 0xfc)); @@ -115,13 +118,16 @@ grackle_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, static status_t grackle_write_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value) + uint16 offset, uint8 size, uint32 value) { grackle_host_bridge *bridge = (grackle_host_bridge*)cookie; TRACE("grackle_write_pci_config(bus=%u, dev=%u, func=%u, offset=%u, " "size=%u, value=%lu)\n", (int)bus, (int)device, (int)function, (int)offset, (int)size, value); + if (offset > 0xff) + return B_BAD_VALUE; + out32rb(bridge->address_registers, (1 << 31) | (bus << 16) | ((device & 0x1f) << 11) | ((function & 0x7) << 8) | (offset & 0xfc)); diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/uninorth.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/uninorth.cpp index d7a1f4c0ea..7997129f79 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/uninorth.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/ppc/openfirmware/uninorth.cpp @@ -74,9 +74,9 @@ static int uninorth_enable_config(struct uninorth_host_bridge *bridge, uint8 bus, uint8 slot, uint8 function, uint8 offset); static status_t uninorth_read_pci_config(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 offset, uint8 size, uint32 *value); + uint8 function, uint16 offset, uint8 size, uint32 *value); static status_t uninorth_write_pci_config(void *cookie, uint8 bus, - uint8 device, uint8 function, uint8 offset, uint8 size, + uint8 device, uint8 function, uint16 offset, uint8 size, uint32 value); static status_t uninorth_get_max_bus_devices(void *cookie, int32 *count); static status_t uninorth_read_pci_irq(void *cookie, uint8 bus, uint8 device, @@ -95,10 +95,13 @@ static pci_controller sUniNorthPCIController = { static status_t uninorth_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value) + uint16 offset, uint8 size, uint32 *value) { uninorth_host_bridge *bridge = (uninorth_host_bridge*)cookie; + if (offset > 0xff) + return B_BAD_VALUE; + addr_t caoff = bridge->data_registers + (offset & 0x07); if (uninorth_enable_config(bridge, bus, device, function, offset) != 0) { @@ -124,10 +127,13 @@ uninorth_read_pci_config(void *cookie, uint8 bus, uint8 device, uint8 function, static status_t uninorth_write_pci_config(void *cookie, uint8 bus, uint8 device, - uint8 function, uint8 offset, uint8 size, uint32 value) + uint8 function, uint16 offset, uint8 size, uint32 value) { uninorth_host_bridge *bridge = (uninorth_host_bridge*)cookie; + if (offset > 0xff) + return B_BAD_VALUE; + addr_t caoff = bridge->data_registers + (offset & 0x07); if (uninorth_enable_config(bridge, bus, device, function, offset)) { diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile index f03f6c7048..980b4504f3 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile @@ -4,7 +4,12 @@ SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; UsePrivateHeaders kernel [ FDirName kernel arch x86 ] [ FDirName kernel util ] ; +SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi acpica include ; +SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi acpica include + platform ; + KernelStaticLibrary pci_arch_bus_manager : + pci_acpi.cpp pci_arch_info.cpp pci_arch_module.cpp pci_bios.cpp diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.cpp new file mode 100644 index 0000000000..f1fb0fad65 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.cpp @@ -0,0 +1,270 @@ +/* + * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved. + * Copyright 2007, Michael Lotz, mmlr@mlotz.ch + * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. +*/ + + +#include "pci_acpi.h" + +#include + +#include + +#include + + +//#define TRACE_ACPI +#ifdef TRACE_ACPI +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + +static struct scan_spots_struct acpi_scan_spots[] = { + { 0x0, 0x1000, 0x1000 }, + { 0x9f000, 0x10000, 0x1000 }, + { 0xe0000, 0x110000, 0x20000 }, + { 0xfd000, 0xfe000, 0x1000}, + { 0, 0, 0 } +}; + +static acpi_descriptor_header* sAcpiRsdt; // System Description Table +static acpi_descriptor_header* sAcpiXsdt; // Extended System Description Table +static int32 sNumEntries = -1; + + +static status_t +acpi_validate_rsdp(acpi_rsdp* rsdp) +{ + const char* data = (const char*)rsdp; + unsigned char checksum = 0; + for (uint32 i = 0; i < sizeof(acpi_rsdp_legacy); i++) + checksum += data[i]; + + if ((checksum & 0xff) != 0) { + TRACE(("acpi: rsdp failed basic checksum\n")); + return B_BAD_DATA; + } + + // for ACPI 2.0+ we need to also validate the extended checksum + if (rsdp->revision > 0) { + for (uint32 i = sizeof(acpi_rsdp_legacy); + i < sizeof(acpi_rsdp_extended); i++) { + checksum += data[i]; + } + + if ((checksum & 0xff) != 0) { + TRACE(("acpi: rsdp failed extended checksum\n")); + return B_BAD_DATA; + } + } + + return B_OK; +} + + +static status_t +acpi_validate_rsdt(acpi_descriptor_header* rsdt) +{ + const char* data = (const char*)rsdt; + unsigned char checksum = 0; + for (uint32 i = 0; i < rsdt->length; i++) + checksum += data[i]; + + return checksum == 0 ? B_OK : B_BAD_DATA; +} + + +static status_t +acpi_check_rsdt(acpi_rsdp* rsdp) +{ + if (acpi_validate_rsdp(rsdp) != B_OK) + return B_BAD_DATA; + + bool usingXsdt = false; + + TRACE(("acpi: found rsdp at %p oem id: %.6s, rev %d\n", + rsdp, rsdp->oem_id, rsdp->revision)); + TRACE(("acpi: rsdp points to rsdt at 0x%lx\n", rsdp->rsdt_address)); + + uint32 length = 0; + acpi_descriptor_header* rsdt = NULL; + area_id rsdtArea = -1; + if (rsdp->revision > 0) { + length = rsdp->xsdt_length; + rsdtArea = map_physical_memory("rsdt acpi", + (uint32)rsdp->xsdt_address, rsdp->xsdt_length, B_ANY_KERNEL_ADDRESS, + B_KERNEL_READ_AREA, (void **)&rsdt); + if (rsdt != NULL + && strncmp(rsdt->signature, ACPI_XSDT_SIGNATURE, 4) != 0) { + delete_area(rsdtArea); + rsdt = NULL; + TRACE(("acpi: invalid extended system description table\n")); + } else + usingXsdt = true; + } + + // if we're ACPI v1 or we fail to map the XSDT for some reason, + // attempt to use the RSDT instead. + if (rsdt == NULL) { + // map and validate the root system description table + rsdtArea = map_physical_memory("rsdt acpi", + rsdp->rsdt_address, sizeof(acpi_descriptor_header), + B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, (void **)&rsdt); + if (rsdt != NULL + && strncmp(rsdt->signature, ACPI_RSDT_SIGNATURE, 4) != 0) { + delete_area(rsdtArea); + rsdt = NULL; + TRACE(("acpi: invalid root system description table\n")); + return B_ERROR; + } + + length = rsdt->length; + // Map the whole table, not just the header + TRACE(("acpi: rsdt length: %lu\n", length)); + delete_area(rsdtArea); + rsdtArea = map_physical_memory("rsdt acpi", + rsdp->rsdt_address, length, B_ANY_KERNEL_ADDRESS, + B_KERNEL_READ_AREA, (void **)&rsdt); + } + + if (rsdt != NULL) { + if (acpi_validate_rsdt(rsdt) != B_OK) { + TRACE(("acpi: rsdt failed checksum validation\n")); + delete_area(rsdtArea); + return B_ERROR; + } else { + if (usingXsdt) + sAcpiXsdt = rsdt; + else + sAcpiRsdt = rsdt; + TRACE(("acpi: found valid %s at %p\n", + usingXsdt ? ACPI_XSDT_SIGNATURE : ACPI_RSDT_SIGNATURE, + rsdt)); + } + } else + return B_ERROR; + + return B_OK; +} + + +template +acpi_descriptor_header* +acpi_find_table_generic(const char* signature, acpi_descriptor_header* acpiSdt) +{ + if (acpiSdt == NULL) + return NULL; + + if (sNumEntries == -1) { + // if using the xsdt, our entries are 64 bits wide. + sNumEntries = (acpiSdt->length + - sizeof(acpi_descriptor_header)) + / sizeof(PointerType); + } + + if (sNumEntries <= 0) { + TRACE(("acpi: root system description table is empty\n")); + return NULL; + } + + TRACE(("acpi: searching %ld entries for table '%.4s'\n", sNumEntries, + signature)); + + PointerType* pointer = (PointerType*)((uint8*)acpiSdt + + sizeof(acpi_descriptor_header)); + + acpi_descriptor_header* header = NULL; + area_id headerArea = -1; + for (int32 j = 0; j < sNumEntries; j++, pointer++) { + headerArea = map_physical_memory("acpi header", (uint32)*pointer, + sizeof(acpi_descriptor_header), B_ANY_KERNEL_ADDRESS, + B_KERNEL_READ_AREA, (void **)&header); + + if (header == NULL + || strncmp(header->signature, signature, 4) != 0) { + // not interesting for us + TRACE(("acpi: Looking for '%.4s'. Skipping '%.4s'\n", + signature, header != NULL ? header->signature : "null")); + + if (header != NULL) { + delete_area(headerArea); + header = NULL; + } + + continue; + } + + TRACE(("acpi: Found '%.4s' @ %p\n", signature, pointer)); + break; + } + + + if (header == NULL) + return NULL; + + // Map the whole table, not just the header + uint32 length = header->length; + delete_area(headerArea); + + headerArea = map_physical_memory("acpi table", + (uint32)*pointer, length, B_ANY_KERNEL_ADDRESS, + B_KERNEL_READ_AREA, (void **)&header); + return header; +} + + +void* +acpi_find_table(const char* signature) +{ + if (sAcpiRsdt != NULL) + return acpi_find_table_generic(signature, sAcpiRsdt); + else if (sAcpiXsdt != NULL) + return acpi_find_table_generic(signature, sAcpiXsdt); + + return NULL; +} + + +void +acpi_init() +{ + // Try to find the ACPI RSDP. + for (int32 i = 0; acpi_scan_spots[i].length > 0; i++) { + acpi_rsdp* rsdp = NULL; + + TRACE(("acpi_init: entry base 0x%lx, limit 0x%lx\n", + acpi_scan_spots[i].start, acpi_scan_spots[i].stop)); + + char* start = NULL; + area_id rsdpArea = map_physical_memory("acpi rsdp", + acpi_scan_spots[i].start, acpi_scan_spots[i].length, + B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, (void **)&start); + if (rsdpArea < B_OK) { + TRACE(("acpi_init: couldn't map %s\n", strerror(rsdpArea))); + break; + } + for (char *pointer = start; + (addr_t)pointer < (addr_t)start + acpi_scan_spots[i].length; + pointer += 16) { + if (strncmp(pointer, ACPI_RSDP_SIGNATURE, 8) == 0) { + TRACE(("acpi_init: found ACPI RSDP signature at %p\n", + pointer)); + rsdp = (acpi_rsdp*)pointer; + } + } + + if (rsdp != NULL && acpi_check_rsdt(rsdp) == B_OK) { + delete_area(rsdpArea); + break; + } + delete_area(rsdpArea); + } + +} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.h b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.h new file mode 100644 index 0000000000..8be385616d --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_acpi.h @@ -0,0 +1,27 @@ +/* + * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef PCI_ACPI_H +#define PCI_ACPI_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct scan_spots_struct { + uint32 start; + uint32 stop; + uint32 length; +}; + +void *acpi_find_table(const char *signature); +void acpi_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* PCI_ACPI_H */ diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp index 1852f70f3b..ef34b2be11 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp @@ -17,7 +17,7 @@ pci_bios_init(void) status_t pci_bios_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value) + uint16 offset, uint8 size, uint32 *value) { return B_ERROR; } @@ -25,7 +25,7 @@ pci_bios_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, status_t pci_bios_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value) + uint16 offset, uint8 size, uint32 value) { return B_ERROR; } diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.h b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.h index 89807f1fd8..64d05b67be 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.h +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.h @@ -7,11 +7,11 @@ status_t pci_bios_init(void); status_t pci_bios_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value); + uint16 offset, uint8 size, uint32 *value); status_t pci_bios_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value); + uint16 offset, uint8 size, uint32 value); status_t pci_bios_get_max_bus_devices(void *cookie, int32 *count); diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp index 4a0fd7fc5a..e702ca78c2 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp @@ -3,14 +3,20 @@ * Distributed under the terms of the MIT License. */ + #include #include #include -#include "pci_irq.h" -#include "pci_bios.h" -#include "pci_private.h" -#include "pci_controller.h" + +#include "pci_acpi.h" #include "arch_cpu.h" +#include "pci_bios.h" +#include "pci_controller.h" +#include "pci_irq.h" +#include "pci_private.h" + +#include "acpi.h" + #define PCI_MECH1_REQ_PORT 0xCF8 #define PCI_MECH1_DATA_PORT 0xCFC @@ -38,11 +44,14 @@ spinlock sConfigLock = B_SPINLOCK_INITIALIZER; static status_t pci_mech1_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value) + uint16 offset, uint8 size, uint32 *value) { cpu_status cpu; status_t status = B_OK; + if (offset > 0xff) + return B_BAD_VALUE; + PCI_LOCK_CONFIG(cpu); out32(PCI_MECH1_REQ_DATA(bus, device, function, offset), PCI_MECH1_REQ_PORT); switch (size) { @@ -67,11 +76,14 @@ pci_mech1_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, static status_t pci_mech1_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value) + uint16 offset, uint8 size, uint32 value) { cpu_status cpu; status_t status = B_OK; + if (offset > 0xff) + return B_BAD_VALUE; + PCI_LOCK_CONFIG(cpu); out32(PCI_MECH1_REQ_DATA(bus, device, function, offset), PCI_MECH1_REQ_PORT); switch (size) { @@ -104,11 +116,14 @@ pci_mech1_get_max_bus_devices(void *cookie, int32 *count) static status_t pci_mech2_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value) + uint16 offset, uint8 size, uint32 *value) { cpu_status cpu; status_t status = B_OK; + if (offset > 0xff) + return B_BAD_VALUE; + PCI_LOCK_CONFIG(cpu); out8((uint8)(0xf0 | (function << 1)), PCI_MECH2_ENABLE_PORT); out8(bus, PCI_MECH2_FORWARD_PORT); @@ -135,11 +150,14 @@ pci_mech2_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, static status_t pci_mech2_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value) + uint16 offset, uint8 size, uint32 value) { cpu_status cpu; status_t status = B_OK; + if (offset > 0xff) + return B_BAD_VALUE; + PCI_LOCK_CONFIG(cpu); out8((uint8)(0xf0 | (function << 1)), PCI_MECH2_ENABLE_PORT); out8(bus, PCI_MECH2_FORWARD_PORT); @@ -172,6 +190,71 @@ pci_mech2_get_max_bus_devices(void *cookie, int32 *count) } +addr_t sPCIeBase = 0; +#define PCIE_VADDR(base, bus, slot, func, reg) ((base) + \ + ((((bus) & 0xff) << 20) | (((slot) & 0x1f) << 15) | \ + (((func) & 0x7) << 12) | ((reg) & 0xfff))) + +static status_t +pci_mechpcie_read_config(void *cookie, uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 *value) +{ + status_t status = B_OK; + + addr_t address = PCIE_VADDR(sPCIeBase, bus, device, function, offset); + + switch (size) { + case 1: + *value = *(uint8*)address; + break; + case 2: + *value = *(uint16*)address; + break; + case 4: + *value = *(uint32*)address; + break; + default: + status = B_ERROR; + break; + } + return status; +} + + +static status_t +pci_mechpcie_write_config(void *cookie, uint8 bus, uint8 device, uint8 function, + uint16 offset, uint8 size, uint32 value) +{ + status_t status = B_OK; + + addr_t address = PCIE_VADDR(sPCIeBase, bus, device, function, offset); + switch (size) { + case 1: + *(uint8*)address = value; + break; + case 2: + *(uint16*)address = value; + break; + case 4: + *(uint32*)address = value; + break; + default: + status = B_ERROR; + break; + } + + return status; +} + + +static status_t +pci_mechpcie_get_max_bus_devices(void *cookie, int32 *count) +{ + *count = 32; + return B_OK; +} + + void * pci_ram_address(const void *physical_address_in_system_memory) { @@ -197,6 +280,15 @@ pci_controller pci_controller_x86_mech2 = pci_x86_irq_write, }; +pci_controller pci_controller_x86_mechpcie = +{ + pci_mechpcie_read_config, + pci_mechpcie_write_config, + pci_mechpcie_get_max_bus_devices, + pci_x86_irq_read, + pci_x86_irq_write, +}; + pci_controller pci_controller_x86_bios = { pci_bios_read_config, @@ -212,6 +304,7 @@ pci_controller_init(void) { bool search_mech1 = true; bool search_mech2 = true; + bool search_mechpcie = true; bool search_bios = true; void *config = NULL; status_t status; @@ -225,11 +318,13 @@ pci_controller_init(void) const char *mech = get_driver_parameter(config, "mechanism", NULL, NULL); if (mech) { - search_mech1 = search_mech2 = search_bios = false; + search_mech1 = search_mech2 = search_mechpcie = search_bios = false; if (strcmp(mech, "1") == 0) search_mech1 = true; else if (strcmp(mech, "2") == 0) search_mech2 = true; + else if (strcmp(mech, "pcie") == 0) + search_mechpcie = true; else if (strcmp(mech, "bios") == 0) search_bios = true; else @@ -240,10 +335,39 @@ pci_controller_init(void) // TODO: check safemode "don't call the BIOS" setting and unset search_bios! - // PCI configuration mechanism 1 is the preferred one. + // PCI configuration mechanism PCIe is the preferred one. + // If it doesn't work, try mechanism 1. // If it doesn't work, try mechanism 2. // Finally, try to fallback to PCI BIOS + if (search_mechpcie) { + acpi_init(); + struct acpi_table_mcfg* mcfg = + (struct acpi_table_mcfg*)acpi_find_table("MCFG"); + if (mcfg != NULL) { + struct acpi_mcfg_allocation* end = (struct acpi_mcfg_allocation*) + ((char*)mcfg + mcfg->Header.Length); + struct acpi_mcfg_allocation* alloc = (struct acpi_mcfg_allocation*) + (mcfg + 1); + for (; alloc < end; alloc++) { + dprintf("PCI: mechanism addr: %" B_PRIx64 ", seg: %x, start: " + "%x, end: %x\n", alloc->Address, alloc->PciSegment, + alloc->StartBusNumber, alloc->EndBusNumber); + if (alloc->PciSegment == 0) { + area_id mcfgArea = map_physical_memory("acpi mcfg", + alloc->Address, (alloc->EndBusNumber + 1) << 20, + B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA + | B_KERNEL_WRITE_AREA, (void **)&sPCIeBase); + if (mcfgArea < 0) + break; + dprintf("PCI: mechanism pcie controller found\n"); + return pci_controller_add(&pci_controller_x86_mechpcie, + NULL); + } + } + } + } + if (search_mech1) { // check for mechanism 1 out32(0x80000000, PCI_MECH1_REQ_PORT); diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index 03658b0f66..f13d492e62 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -43,7 +43,7 @@ pci_get_nth_pci_info(long index, pci_info *outInfo) uint32 -pci_read_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, +pci_read_config(uint8 virtualBus, uint8 device, uint8 function, uint16 offset, uint8 size) { uint8 bus; @@ -62,7 +62,7 @@ pci_read_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, void -pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, +pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint16 offset, uint8 size, uint32 value) { uint8 bus; @@ -75,8 +75,8 @@ pci_write_config(uint8 virtualBus, uint8 device, uint8 function, uint8 offset, status_t -pci_find_capability(uchar virtualBus, uchar device, uchar function, - uchar capID, uchar *offset) +pci_find_capability(uint8 virtualBus, uint8 device, uint8 function, + uint8 capID, uint8 *offset) { uint8 bus; uint8 domain; @@ -87,6 +87,20 @@ pci_find_capability(uchar virtualBus, uchar device, uchar function, } +status_t +pci_find_extended_capability(uint8 virtualBus, uint8 device, uint8 function, + uint16 capID, uint16 *offset) +{ + uint8 bus; + uint8 domain; + if (gPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK) + return B_ERROR; + + return gPCI->FindExtendedCapability(domain, bus, device, function, capID, + offset); +} + + status_t pci_reserve_device(uchar virtualBus, uchar device, uchar function, const char *driverName, void *nodeCookie) @@ -1138,6 +1152,7 @@ PCI::_CreateDevice(PCIBus *parent, uint8 device, uint8 function) newDev->bus = parent->bus; newDev->device = device; newDev->function = function; + memset(&newDev->info, 0, sizeof(newDev->info)); _ReadBasicInfo(newDev); @@ -1172,9 +1187,9 @@ PCI::_BarSize(uint32 bits, uint32 mask) } -void +size_t PCI::_GetBarInfo(PCIDev *dev, uint8 offset, uint32 *_address, uint32 *_size, - uint8 *_flags) + uint8 *_flags, uint32 *_highAddress) { uint32 oldValue = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, offset, 4); @@ -1185,11 +1200,21 @@ PCI::_GetBarInfo(PCIDev *dev, uint8 offset, uint32 *_address, uint32 *_size, WriteConfig(dev->domain, dev->bus, dev->device, dev->function, offset, 4, oldValue); - *_address = oldValue & PCI_address_memory_32_mask; + uint32 mask = PCI_address_memory_32_mask; + bool is64bit = (oldValue & PCI_address_type_64) != 0; + if ((oldValue & PCI_address_space) == PCI_address_space) + mask = PCI_address_io_mask; + else if (is64bit && _highAddress != NULL) { + *_highAddress = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, offset + 4, 4); + } + + *_address = oldValue & mask; if (_size != NULL) - *_size = _BarSize(newValue, PCI_address_memory_32_mask); + *_size = _BarSize(newValue, mask); if (_flags != NULL) - *_flags = newValue & 0xf; + *_flags = oldValue & ~mask; + return is64bit ? 2 : 1; } @@ -1270,11 +1295,15 @@ PCI::_ReadHeaderInfo(PCIDev *dev) // get BAR size infos _GetRomBarInfo(dev, PCI_rom_base, &dev->info.u.h0.rom_base_pci, &dev->info.u.h0.rom_size); - for (int i = 0; i < 6; i++) { - _GetBarInfo(dev, PCI_base_registers + 4*i, + for (int i = 0; i < 6;) { + size_t barSize = _GetBarInfo(dev, PCI_base_registers + 4 * i, &dev->info.u.h0.base_registers_pci[i], &dev->info.u.h0.base_register_sizes[i], - &dev->info.u.h0.base_register_flags[i]); + &dev->info.u.h0.base_register_flags[i], + i < 5 ? &dev->info.u.h0.base_registers_pci[i + 1] : NULL); + dev->info.u.h0.base_registers[i] = (addr_t)pci_ram_address( + (void *)(addr_t)dev->info.u.h0.base_registers_pci[i]); + i += barSize; } // restore PCI device address decoding @@ -1283,10 +1312,6 @@ PCI::_ReadHeaderInfo(PCIDev *dev) dev->info.u.h0.rom_base = (addr_t)pci_ram_address( (void *)(addr_t)dev->info.u.h0.rom_base_pci); - for (int i = 0; i < 6; i++) { - dev->info.u.h0.base_registers[i] = (addr_t)pci_ram_address( - (void *)(addr_t)dev->info.u.h0.base_registers_pci[i]); - } dev->info.u.h0.cardbus_cis = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, PCI_cardbus_cis, 4); @@ -1316,11 +1341,15 @@ PCI::_ReadHeaderInfo(PCIDev *dev) _GetRomBarInfo(dev, PCI_bridge_rom_base, &dev->info.u.h1.rom_base_pci); - for (int i = 0; i < 2; i++) { - _GetBarInfo(dev, PCI_base_registers + 4*i, + for (int i = 0; i < 2;) { + size_t barSize = _GetBarInfo(dev, PCI_base_registers + 4 * i, &dev->info.u.h1.base_registers_pci[i], &dev->info.u.h1.base_register_sizes[i], - &dev->info.u.h1.base_register_flags[i]); + &dev->info.u.h1.base_register_flags[i], + i < 5 ? &dev->info.u.h1.base_registers_pci[i + 1] : NULL); + dev->info.u.h1.base_registers[i] = (addr_t)pci_ram_address( + (void *)(addr_t)dev->info.u.h1.base_registers_pci[i]); + i += barSize; } // restore PCI device address decoding @@ -1329,10 +1358,6 @@ PCI::_ReadHeaderInfo(PCIDev *dev) dev->info.u.h1.rom_base = (addr_t)pci_ram_address( (void *)(addr_t)dev->info.u.h1.rom_base_pci); - for (int i = 0; i < 2; i++) { - dev->info.u.h1.base_registers[i] = (addr_t)pci_ram_address( - (void *)(addr_t)dev->info.u.h1.base_registers_pci[i]); - } dev->info.u.h1.primary_bus = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, PCI_primary_bus, 1); @@ -1456,7 +1481,7 @@ PCI::_RefreshDeviceInfo(PCIBus *bus) status_t PCI::ReadConfig(uint8 domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value) + uint16 offset, uint8 size, uint32 *value) { domain_data *info = _GetDomainData(domain); if (!info) @@ -1479,7 +1504,7 @@ PCI::ReadConfig(uint8 domain, uint8 bus, uint8 device, uint8 function, uint32 PCI::ReadConfig(uint8 domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size) + uint16 offset, uint8 size) { uint32 value; if (ReadConfig(domain, bus, device, function, offset, size, &value) @@ -1491,7 +1516,7 @@ PCI::ReadConfig(uint8 domain, uint8 bus, uint8 device, uint8 function, uint32 -PCI::ReadConfig(PCIDev *device, uint8 offset, uint8 size) +PCI::ReadConfig(PCIDev *device, uint16 offset, uint8 size) { uint32 value; if (ReadConfig(device->domain, device->bus, device->device, @@ -1504,7 +1529,7 @@ PCI::ReadConfig(PCIDev *device, uint8 offset, uint8 size) status_t PCI::WriteConfig(uint8 domain, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value) + uint16 offset, uint8 size, uint32 value) { domain_data *info = _GetDomainData(domain); if (!info) @@ -1526,7 +1551,7 @@ PCI::WriteConfig(uint8 domain, uint8 bus, uint8 device, uint8 function, status_t -PCI::WriteConfig(PCIDev *device, uint8 offset, uint8 size, uint32 value) +PCI::WriteConfig(PCIDev *device, uint16 offset, uint8 size, uint32 value) { return WriteConfig(device->domain, device->bus, device->device, device->function, offset, size, value); @@ -1537,14 +1562,10 @@ status_t PCI::FindCapability(uint8 domain, uint8 bus, uint8 device, uint8 function, uint8 capID, uint8 *offset) { - if (offset == NULL) { - TRACE_CAP("PCI: FindCapability() ERROR %u:%u:%u capability %#02x offset NULL pointer\n", bus, device, function, capID); - return B_BAD_VALUE; - } - uint16 status = ReadConfig(domain, bus, device, function, PCI_status, 2); if (!(status & PCI_status_capabilities)) { - TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x not supported\n", bus, device, function, capID); + FLOW("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x " + "not supported\n", bus, device, function, capID); return B_ERROR; } @@ -1555,27 +1576,29 @@ PCI::FindCapability(uint8 domain, uint8 bus, uint8 device, uint8 function, switch (headerType & PCI_header_type_mask) { case PCI_header_type_generic: case PCI_header_type_PCI_to_PCI_bridge: - capPointer = ReadConfig(domain, bus, device, function, - PCI_capabilities_ptr, 1); + capPointer = PCI_capabilities_ptr; break; case PCI_header_type_cardbus: - capPointer = ReadConfig(domain, bus, device, function, - PCI_capabilities_ptr_2, 1); + capPointer = PCI_capabilities_ptr_2; break; default: - TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x unknown header type\n", bus, device, function, capID); + TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability " + "%#02x unknown header type\n", bus, device, function, capID); return B_ERROR; } + capPointer = ReadConfig(domain, bus, device, function, capPointer, 1); capPointer &= ~3; if (capPointer == 0) { - TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x empty list\n", bus, device, function, capID); + TRACE_CAP("PCI: find_pci_capability ERROR %u:%u:%u capability %#02x " + "empty list\n", bus, device, function, capID); return B_NAME_NOT_FOUND; } for (int i = 0; i < 48; i++) { if (ReadConfig(domain, bus, device, function, capPointer, 1) == capID) { - *offset = capPointer; + if (offset != NULL) + *offset = capPointer; return B_OK; } @@ -1600,6 +1623,51 @@ PCI::FindCapability(PCIDev *device, uint8 capID, uint8 *offset) } +status_t +PCI::FindExtendedCapability(uint8 domain, uint8 bus, uint8 device, + uint8 function, uint16 capID, uint16 *offset) +{ + if (FindCapability(domain, bus, device, function, PCI_cap_id_pcie) + != B_OK) { + FLOW("PCI:FindExtendedCapability ERROR %u:%u:%u capability %#02x " + "not supported\n", bus, device, function, capID); + return B_ERROR; + } + uint16 capPointer = PCI_extended_capability; + uint32 capability = ReadConfig(domain, bus, device, function, + capPointer, 4); + + if (capability == 0 || capability == 0xffffffff) + return B_NAME_NOT_FOUND; + + for (int i = 0; i < 48; i++) { + if (PCI_extcap_id(capability) == capID) { + if (offset != NULL) + *offset = capPointer; + return B_OK; + } + + capPointer = PCI_extcap_next_ptr(capability) & ~3; + if (capPointer < PCI_extended_capability) + return B_NAME_NOT_FOUND; + capability = ReadConfig(domain, bus, device, function, + capPointer, 4); + } + + TRACE_CAP("PCI:FindExtendedCapability ERROR %u:%u:%u capability %#04x " + "circular list\n", bus, device, function, capID); + return B_ERROR; +} + + +status_t +PCI::FindExtendedCapability(PCIDev *device, uint16 capID, uint16 *offset) +{ + return FindExtendedCapability(device->domain, device->bus, device->device, + device->function, capID, offset); +} + + PCIDev * PCI::FindDevice(uint8 domain, uint8 bus, uint8 device, uint8 function) { diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index 921aebc9ec..2b5f57eabc 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -77,24 +77,29 @@ public: status_t GetNthInfo(long index, pci_info *outInfo); status_t ReadConfig(uint8 domain, uint8 bus, uint8 device, - uint8 function, uint8 offset, uint8 size, + uint8 function, uint16 offset, uint8 size, uint32 *value); uint32 ReadConfig(uint8 domain, uint8 bus, uint8 device, - uint8 function, uint8 offset, uint8 size); - uint32 ReadConfig(PCIDev *device, uint8 offset, + uint8 function, uint16 offset, uint8 size); + uint32 ReadConfig(PCIDev *device, uint16 offset, uint8 size); status_t WriteConfig(uint8 domain, uint8 bus, uint8 device, - uint8 function, uint8 offset, uint8 size, + uint8 function, uint16 offset, uint8 size, uint32 value); - status_t WriteConfig(PCIDev *device, uint8 offset, + status_t WriteConfig(PCIDev *device, uint16 offset, uint8 size, uint32 value); status_t FindCapability(uint8 domain, uint8 bus, uint8 device, uint8 function, uint8 capID, - uint8 *offset); + uint8 *offset = NULL); status_t FindCapability(PCIDev *device, uint8 capID, - uint8 *offset); + uint8 *offset = NULL); + status_t FindExtendedCapability(uint8 domain, uint8 bus, + uint8 device, uint8 function, uint16 capID, + uint16 *offset = NULL); + status_t FindExtendedCapability(PCIDev *device, + uint16 capID, uint16 *offset = NULL); status_t ResolveVirtualBus(uint8 virtualBus, uint8 *domain, uint8 *bus); @@ -134,9 +139,9 @@ private: void _RefreshDeviceInfo(PCIBus *bus); uint32 _BarSize(uint32 bits, uint32 mask); - void _GetBarInfo(PCIDev *dev, uint8 offset, + size_t _GetBarInfo(PCIDev *dev, uint8 offset, uint32 *address, uint32 *size = 0, - uint8 *flags = 0); + uint8 *flags = 0, uint32 *highAddress = 0); void _GetRomBarInfo(PCIDev *dev, uint8 offset, uint32 *address, uint32 *size = 0, uint8 *flags = 0); @@ -181,9 +186,9 @@ void pci_uninit(void); long pci_get_nth_pci_info(long index, pci_info *outInfo); uint32 pci_read_config(uint8 virtualBus, uint8 device, uint8 function, - uint8 offset, uint8 size); + uint16 offset, uint8 size); void pci_write_config(uint8 virtualBus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value); + uint16 offset, uint8 size, uint32 value); void __pci_resolve_virtual_bus(uint8 virtualBus, uint8 *domain, uint8 *bus); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_controller.h b/src/add-ons/kernel/bus_managers/pci/pci_controller.h index 0c39c35106..3a37e80ccd 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_controller.h +++ b/src/add-ons/kernel/bus_managers/pci/pci_controller.h @@ -13,12 +13,12 @@ typedef struct pci_controller // read PCI config space status_t (*read_pci_config)(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 *value); + uint16 offset, uint8 size, uint32 *value); // write PCI config space status_t (*write_pci_config)(void *cookie, uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value); + uint16 offset, uint8 size, uint32 value); status_t (*get_max_bus_devices)(void *cookie, int32 *count); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_device.cpp b/src/add-ons/kernel/bus_managers/pci/pci_device.cpp index 32a885de71..3d6f8e16f6 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_device.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_device.cpp @@ -66,14 +66,14 @@ pci_device_write_io_32(pci_device* device, addr_t mappedIOAddress, uint32 value) static uint32 -pci_device_read_pci_config(pci_device* device, uint8 offset, uint8 size) +pci_device_read_pci_config(pci_device* device, uint16 offset, uint8 size) { return gPCI->ReadConfig(device->device, offset, size); } static void -pci_device_write_pci_config(pci_device* device, uint8 offset, uint8 size, +pci_device_write_pci_config(pci_device* device, uint16 offset, uint8 size, uint32 value) { gPCI->WriteConfig(device->device, offset, size, value); @@ -94,6 +94,14 @@ pci_device_find_capability(pci_device* device, uint8 capID, uint8* offset) } +static status_t +pci_device_find_extended_capability(pci_device* device, uint16 capID, + uint16* offset) +{ + return gPCI->FindExtendedCapability(device->device, capID, offset); +} + + static void pci_device_get_pci_info(pci_device* device, struct pci_info* info) { @@ -187,5 +195,6 @@ pci_device_module_info gPCIDeviceModule = { pci_device_read_pci_config, pci_device_write_pci_config, pci_device_find_capability, - pci_device_get_pci_info + pci_device_get_pci_info, + pci_device_find_extended_capability }; diff --git a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp index ccc7ecfa1d..e5758f2d85 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp @@ -26,6 +26,7 @@ #endif const char *get_capability_name(uint8 cap_id); +const char *get_extended_capability_name(uint16 cap_id); static void @@ -47,7 +48,7 @@ print_pci2pci_bridge_info(const pci_info *info, bool verbose) uint32 memory_base = ((uint32)info->u.h1.memory_base & 0xfff0) << 16; uint32 memory_limit = (((uint32)info->u.h1.memory_limit & 0xfff0) << 16) + 0xfffff; - TRACE(("PCI: memory window %04" B_PRIx32 "-%04" B_PRIx32 "\n", + TRACE(("PCI: memory window %08" B_PRIx32 "-%08" B_PRIx32 "\n", memory_base, memory_limit)); uint64 prefetchable_memory_base = ((uint32)info->u.h1.prefetchable_memory_base & 0xfff0) << 16; @@ -176,6 +177,45 @@ print_capabilities(const pci_info *info) } +static void +print_extended_capabilities(const pci_info *info) +{ + if (pci_find_capability(info->bus, info->device, info->function, + PCI_cap_id_pcie, NULL) != B_OK) + return; + + uint16 capPointer = PCI_extended_capability; + uint32 capability = pci_read_config(info->bus, info->device, + info->function, capPointer, 4); + TRACE(("PCI: Extended capabilities: ")); + if (capability == 0 || capability == 0xffffffff) { + TRACE(("(empty list)\n")); + return; + } + + for (int i = 0; i < 48; i++) { + if (i) { + TRACE((", ")); + } + const char *name = get_extended_capability_name( + PCI_extcap_id(capability)); + if (name) { + TRACE(("%s", name)); + } else { + TRACE(("0x%04" B_PRIx32, PCI_extcap_id(capability))); + } + + capPointer = PCI_extcap_next_ptr(capability) & ~3; + if (capPointer < PCI_extended_capability) + break; + capability = pci_read_config(info->bus, info->device, info->function, + capPointer, 4); + } + + TRACE(("\n")); +} + + static void print_info_basic(const pci_info *info, bool verbose) { @@ -236,6 +276,7 @@ print_info_basic(const pci_info *info, bool verbose) } print_capabilities(info); + print_extended_capabilities(info); } @@ -298,3 +339,71 @@ get_capability_name(uint8 cap_id) } } + +const char * +get_extended_capability_name(uint16 cap_id) +{ + switch (cap_id) { + case PCI_extcap_id_aer: + return "Advanced Error Reporting"; + case PCI_extcap_id_vc: + return "Virtual Channel"; + case PCI_extcap_id_serial: + return "Serial Number"; + case PCI_extcap_id_power_budget: + return "Power Budgeting"; + case PCI_extcap_id_rcl_decl: + return "Root Complex Link Declaration"; + case PCI_extcap_id_rcil_ctl: + return "Root Complex Internal Link Control"; + case PCI_extcap_id_rcec_assoc: + return "Root Complex Event Collector Association"; + case PCI_extcap_id_mfvc: + return "MultiFunction Virtual Channel"; + case PCI_extcap_id_vc2: + return "Virtual Channel 2"; + case PCI_extcap_id_rcrb_header: + return "RCRB Header"; + case PCI_extcap_id_vendor: + return "Vendor Unique"; + case PCI_extcap_id_acs: + return "Access Control Services"; + case PCI_extcap_id_ari: + return "Alternative Routing Id Interpretation"; + case PCI_extcap_id_ats: + return "Address Translation Services"; + case PCI_extcap_id_srio_virtual: + return "Single Root I/O Virtualization"; + case PCI_extcap_id_mrio_virtual: + return "Multiple Root I/O Virtual"; + case PCI_extcap_id_multicast: + return "Multicast"; + case PCI_extcap_id_page_request: + return "Page Request"; + case PCI_extcap_id_amd: + return "AMD Reserved"; + case PCI_extcap_id_resizable_bar: + return "Resizable Bar"; + case PCI_extcap_id_dyn_power_alloc: + return "Dynamic Power Allocation"; + case PCI_extcap_id_tph_requester: + return "TPH Requester"; + case PCI_extcap_id_latency_tolerance: + return "Latency Tolerance Reporting"; + case PCI_extcap_id_2ndpcie: + return "Secondary PCIe"; + case PCI_extcap_id_pmux: + return "Protocol Multiplexing"; + case PCI_extcap_id_pasid: + return "Process Address Space Id"; + case PCI_extcap_id_ln_requester: + return "LN Requester"; + case PCI_extcap_id_dpc: + return "Downstream Porto Containment"; + case PCI_extcap_id_l1pm: + return "L1 Power Management Substates"; + default: + return NULL; + } +} + diff --git a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp index fc71f6c2f8..41227b1746 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp @@ -67,7 +67,8 @@ static struct pci_module_info sOldPCIModule = { &pci_find_capability, &pci_reserve_device, &pci_unreserve_device, - &pci_update_interrupt_line + &pci_update_interrupt_line, + &pci_find_extended_capability }; module_dependency module_dependencies[] = { diff --git a/src/add-ons/kernel/bus_managers/pci/pci_private.h b/src/add-ons/kernel/bus_managers/pci/pci_private.h index 973dc417b8..306b3d854c 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_private.h +++ b/src/add-ons/kernel/bus_managers/pci/pci_private.h @@ -29,11 +29,11 @@ typedef struct pci_root_module_info { // read PCI config space uint32 (*read_pci_config)(uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size); + uint16 offset, uint8 size); // write PCI config space void (*write_pci_config)(uint8 bus, uint8 device, uint8 function, - uint8 offset, uint8 size, uint32 value); + uint16 offset, uint8 size, uint32 value); } pci_root_module_info; extern pci_root_module_info gPCIRootModule; @@ -46,7 +46,10 @@ extern "C" { void * pci_ram_address(const void *physical_address_in_system_memory); -status_t pci_find_capability(uchar bus, uchar device, uchar function, uchar cap_id, uchar *offset); +status_t pci_find_capability(uint8 bus, uint8 device, uint8 function, + uint8 cap_id, uint8 *offset); +status_t pci_find_extended_capability(uint8 bus, uint8 device, uint8 function, + uint16 cap_id, uint16 *offset); status_t pci_reserve_device(uchar virtualBus, uchar device, uchar function, const char *driverName, void *nodeCookie); diff --git a/src/add-ons/kernel/bus_managers/scsi/busses.cpp b/src/add-ons/kernel/bus_managers/scsi/busses.cpp index 59cfd28f18..d5a17d4c3c 100644 --- a/src/add-ons/kernel/bus_managers/scsi/busses.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/busses.cpp @@ -217,29 +217,30 @@ scsi_init_bus(device_node *node, void **cookie) bus->dma_params.max_sg_block_size &= ~bus->dma_params.alignment; if (bus->dma_params.alignment > B_PAGE_SIZE) { - SHOW_ERROR(0, "Alignment (0x%x) must be less then B_PAGE_SIZE", - (int)bus->dma_params.alignment); + SHOW_ERROR(0, "Alignment (0x%" B_PRIx32 ") must be less then " + "B_PAGE_SIZE", bus->dma_params.alignment); res = B_ERROR; goto err; } if (bus->dma_params.max_sg_block_size < 1) { - SHOW_ERROR(0, "Max s/g block size (0x%x) is too small", - (int)bus->dma_params.max_sg_block_size); + SHOW_ERROR(0, "Max s/g block size (0x%" B_PRIx32 ") is too small", + bus->dma_params.max_sg_block_size); res = B_ERROR; goto err; } if (bus->dma_params.dma_boundary < B_PAGE_SIZE - 1) { - SHOW_ERROR(0, "DMA boundary (0x%x) must be at least B_PAGE_SIZE", - (int)bus->dma_params.dma_boundary); + SHOW_ERROR(0, "DMA boundary (0x%" B_PRIx32 ") must be at least " + "B_PAGE_SIZE", bus->dma_params.dma_boundary); res = B_ERROR; goto err; } if (bus->dma_params.max_blocks < 1 || bus->dma_params.max_sg_blocks < 1) { - SHOW_ERROR(0, "Max blocks (%d) and max s/g blocks (%d) must be at least 1", - (int)bus->dma_params.max_blocks, (int)bus->dma_params.max_sg_blocks); + SHOW_ERROR(0, "Max blocks (%" B_PRIu32 ") and max s/g blocks (%" + B_PRIu32 ") must be at least 1", bus->dma_params.max_blocks, + bus->dma_params.max_sg_blocks); res = B_ERROR; goto err; } diff --git a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp index ef548102c6..06bd010a17 100644 --- a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp @@ -83,8 +83,8 @@ is_sg_list_dma_safe(scsi_ccb *request) // verify entry size if (sg_list->size > max_sg_block_size) { - SHOW_FLOW(0, "S/G-entry is too long (%d/%d bytes)", - (int)sg_list->size, (int)max_sg_block_size); + SHOW_FLOW(0, "S/G-entry is too long (%" B_PRIuPHYSADDR "/%" B_PRIu32 + " bytes)", sg_list->size, max_sg_block_size); return false; } } @@ -103,7 +103,7 @@ scsi_copy_dma_buffer(scsi_ccb *request, uint32 size, bool to_buffer) uint32 num_vecs = buffer->sg_count_orig; uchar *buffer_data = buffer->address; - SHOW_FLOW(1, "to_buffer=%d, %d bytes", to_buffer, (int)size); + SHOW_FLOW(1, "to_buffer=%d, %" B_PRIu32 " bytes", to_buffer, size); // survive even if controller returned invalid data size size = min_c(size, request->data_length); @@ -154,10 +154,8 @@ scsi_free_dma_buffer(dma_buffer *buffer) static bool scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) { - size_t sg_list_size, sg_list_entries; - // free old buffer first - scsi_free_dma_buffer( buffer ); + scsi_free_dma_buffer(buffer); // just in case alignment is ridiculously huge size = (size + dma_params->alignment) & ~dma_params->alignment; @@ -171,14 +169,14 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) uint32 boundary = dma_params->dma_boundary; // alright - a contiguous buffer is required to keep S/G table short - SHOW_INFO(1, "need to setup contiguous DMA buffer of size %d", - (int)size); + SHOW_INFO(1, "need to setup contiguous DMA buffer of size %" B_PRIu32, + size); // verify that we don't get problems with dma boundary if (boundary != ~(uint32)0) { if (size > boundary + 1) { - SHOW_ERROR(2, "data is longer then maximum DMA transfer len (%d/%d bytes)", - (int)size, (int)boundary + 1); + SHOW_ERROR(2, "data is longer then maximum DMA transfer len (%" + B_PRId32 "/%" B_PRId32 " bytes)", size, boundary + 1); return false; } } @@ -199,8 +197,8 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) (void**)&buffer->address); if (buffer->area < 0) { - SHOW_ERROR(2, "Cannot create contignous DMA buffer of %d bytes", - (int)size); + SHOW_ERROR(2, "Cannot create contignous DMA buffer of %" B_PRIu32 + " bytes", size); return false; } @@ -212,8 +210,8 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) B_32_BIT_FULL_LOCK, 0); // TODO: Use B_FULL_LOCK, if possible! if (buffer->area < 0) { - SHOW_ERROR(2, "Cannot create DMA buffer of %d bytes", - (int)size); + SHOW_ERROR(2, "Cannot create DMA buffer of %" B_PRIu32 " bytes", + size); return false; } @@ -222,7 +220,7 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) // create S/G list // worst case is one entry per page, and size is page-aligned - sg_list_size = buffer->size / B_PAGE_SIZE * sizeof( physical_entry ); + size_t sg_list_size = buffer->size / B_PAGE_SIZE * sizeof( physical_entry ); // create_area has page-granularity sg_list_size = (sg_list_size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); @@ -231,15 +229,15 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) B_32_BIT_FULL_LOCK, 0); // TODO: Use B_FULL_LOCK, if possible! if (buffer->sg_list_area < 0) { - SHOW_ERROR( 2, "Cannot craete DMA buffer S/G list of %d bytes", - (int)sg_list_size ); + SHOW_ERROR( 2, "Cannot create DMA buffer S/G list of %" B_PRIuSIZE + " bytes", sg_list_size ); delete_area(buffer->area); buffer->area = 0; return false; } - sg_list_entries = sg_list_size / sizeof( physical_entry ); + size_t sg_list_entries = sg_list_size / sizeof(physical_entry); { size_t mapped_len; @@ -255,8 +253,9 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) &mapped_len ); if( res != B_OK || mapped_len != buffer->size ) { - SHOW_ERROR(0, "Error creating S/G list for DMA buffer (%s; wanted %d, got %d bytes)", - strerror(res), (int)mapped_len, (int)buffer->size); + SHOW_ERROR(0, "Error creating S/G list for DMA buffer (%s; wanted " + "%" B_PRIuSIZE ", got %" B_PRIuSIZE " bytes)", strerror(res), + mapped_len, buffer->size); } } @@ -278,7 +277,7 @@ scsi_free_dma_buffer_sg_orig(dma_buffer *buffer) /** allocate S/G list to original data */ static bool -scsi_alloc_dma_buffer_sg_orig(dma_buffer *buffer, int size) +scsi_alloc_dma_buffer_sg_orig(dma_buffer *buffer, size_t size) { // free old list first scsi_free_dma_buffer_sg_orig(buffer); @@ -290,15 +289,15 @@ scsi_alloc_dma_buffer_sg_orig(dma_buffer *buffer, int size) B_ANY_KERNEL_ADDRESS, size, B_NO_LOCK, 0); if (buffer->sg_orig < 0) { - SHOW_ERROR(2, "Cannot S/G list buffer to original data of %d bytes", - (int)size); + SHOW_ERROR(2, "Cannot S/G list buffer to original data of %" B_PRIuSIZE + " bytes", size); return false; } buffer->sg_count_max_orig = size / sizeof(physical_entry); - SHOW_INFO(3, "Got up to %d S/G entries to original data", - (int)buffer->sg_count_max_orig); + SHOW_INFO(3, "Got up to %" B_PRIuSIZE " S/G entries to original data", + buffer->sg_count_max_orig); return true; } @@ -311,11 +310,11 @@ dump_sg_table(const physical_entry *sg_list, { uint32 cur_idx; - SHOW_FLOW(1, "count=%d", (int)sg_list_count); + SHOW_FLOW(1, "count=%" B_PRIu32, sg_list_count); for (cur_idx = sg_list_count; cur_idx >= 1; --cur_idx, ++sg_list) { - SHOW_FLOW(1, "addr=%" B_PRIxPHYSADDR ", size=%d", sg_list->address, - (int)sg_list->size); + SHOW_FLOW(1, "addr=%" B_PRIxPHYSADDR ", size=%" B_PRIuPHYSADDR, + sg_list->address, sg_list->size); } } @@ -404,7 +403,7 @@ scsi_get_dma_buffer(scsi_ccb *request) request->sg_list = buffer->sg_list; request->sg_count = buffer->sg_count; - SHOW_INFO(1, "bytes: %d", (int)request->data_length); + SHOW_INFO(1, "bytes: %" B_PRIu32, request->data_length); SHOW_INFO0(3, "we can start now"); request->buffered = true; @@ -434,9 +433,9 @@ scsi_release_dma_buffer(scsi_ccb *request) scsi_device_info *device = request->device; dma_buffer *buffer = request->dma_buffer; - SHOW_FLOW(1, "Buffering finished, %x, %x", + SHOW_FLOW(1, "Buffering finished, %x, %" B_PRIx32, request->subsys_status & SCSI_SUBSYS_STATUS_MASK, - (int)(request->flags & SCSI_DIR_MASK)); + (request->flags & SCSI_DIR_MASK)); // copy data from buffer if required and if operation succeeded if ((request->subsys_status & SCSI_SUBSYS_STATUS_MASK) == SCSI_REQ_CMP diff --git a/src/add-ons/kernel/bus_managers/scsi/emulation.cpp b/src/add-ons/kernel/bus_managers/scsi/emulation.cpp index 161b27395e..840517a4a0 100644 --- a/src/add-ons/kernel/bus_managers/scsi/emulation.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/emulation.cpp @@ -167,7 +167,6 @@ scsi_start_mode_sense_6(scsi_ccb *request) { scsi_cmd_mode_sense_6 *cmd = (scsi_cmd_mode_sense_6 *)request->orig_cdb; scsi_cmd_mode_sense_10 *cdb = (scsi_cmd_mode_sense_10 *)request->cdb; - size_t allocationLength; SHOW_FLOW0(3, "patching MODE SENSE(6) to MODE SENSE(10)"); @@ -180,11 +179,11 @@ scsi_start_mode_sense_6(scsi_ccb *request) cdb->page_code = cmd->page_code; cdb->page_control = cmd->page_control; - allocationLength = cmd->allocation_length + size_t allocationLength = cmd->allocation_length - sizeof(scsi_cmd_mode_sense_6) + sizeof(scsi_cmd_mode_sense_10); cdb->allocation_length = B_HOST_TO_BENDIAN_INT16(allocationLength); - SHOW_FLOW(3, "allocation_length=%ld", allocationLength); + SHOW_FLOW(3, "allocation_length=%" B_PRIuSIZE, allocationLength); cdb->control = cmd->control; diff --git a/src/add-ons/kernel/bus_managers/scsi/scatter_gather.cpp b/src/add-ons/kernel/bus_managers/scsi/scatter_gather.cpp index 2d4977f430..cae10b51b8 100644 --- a/src/add-ons/kernel/bus_managers/scsi/scatter_gather.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/scatter_gather.cpp @@ -37,7 +37,6 @@ fill_temp_sg(scsi_ccb *ccb) }; size_t num_entries; size_t mapped_len; - uint32 cur_idx; physical_entry *temp_sg = (physical_entry *)ccb->sg_list; res = get_iovec_memory_map(&vec, 1, 0, ccb->data_length, temp_sg, max_sg_blocks, @@ -54,10 +53,10 @@ fill_temp_sg(scsi_ccb *ccb) if (dma_boundary != ~(uint32)0 || ccb->data_length > max_sg_block_size) { // S/G list may not be controller-compatible: // we have to split offending entries - SHOW_FLOW(3, "Checking violation of dma boundary 0x%x and entry size 0x%x", - (int)dma_boundary, (int)max_sg_block_size); + SHOW_FLOW(3, "Checking violation of dma boundary 0x%" B_PRIx32 + " and entry size 0x%" B_PRIx32, dma_boundary, max_sg_block_size); - for (cur_idx = 0; cur_idx < num_entries; ++cur_idx) { + for (uint32 cur_idx = 0; cur_idx < num_entries; ++cur_idx) { addr_t max_len; // calculate space upto next dma boundary crossing @@ -66,10 +65,10 @@ fill_temp_sg(scsi_ccb *ccb) // restrict size per sg item max_len = std::min(max_len, (addr_t)max_sg_block_size); - SHOW_FLOW(4, "addr=%#" B_PRIxPHYSADDR ", size=%x, max_len=%x, " - "idx=%d, num=%d", temp_sg[cur_idx].address, - (int)temp_sg[cur_idx].size, (int)max_len, (int)cur_idx, - (int)num_entries); + SHOW_FLOW(4, "addr=%#" B_PRIxPHYSADDR ", size=%" B_PRIxPHYSADDR + ", max_len=%" B_PRIxADDR ", idx=%" B_PRId32 ", num=%" + B_PRIuSIZE, temp_sg[cur_idx].address, temp_sg[cur_idx].size, + max_len, cur_idx, num_entries); if (max_len < temp_sg[cur_idx].size) { // split sg block @@ -153,8 +152,8 @@ cleanup_tmp_sg(scsi_ccb *ccb) { status_t res; - SHOW_FLOW(3, "ccb=%p, data=%p, data_length=%d", - ccb, ccb->data, (int)ccb->data_length); + SHOW_FLOW(3, "ccb=%p, data=%p, data_length=%" B_PRId32, + ccb, ccb->data, ccb->data_length); res = unlock_memory(ccb->data, ccb->data_length, B_DMA_IO | ((ccb->flags & SCSI_DIR_MASK) == SCSI_DIR_IN ? B_READ_DEVICE : 0)); diff --git a/src/add-ons/kernel/bus_managers/scsi/scsi_io.cpp b/src/add-ons/kernel/bus_managers/scsi/scsi_io.cpp index 23663d9cfc..80acf4f20a 100644 --- a/src/add-ons/kernel/bus_managers/scsi/scsi_io.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/scsi_io.cpp @@ -277,9 +277,9 @@ scsi_request_finished(scsi_ccb *request, uint num_requests) && request->device_status == SCSI_STATUS_CHECK_CONDITION; if (request->subsys_status != SCSI_REQ_CMP) { - SHOW_FLOW(3, "subsys=%x, device=%x, flags=%x, manual_auto_sense=%d", - request->subsys_status, request->device_status, (int)request->flags, - device->manual_autosense); + SHOW_FLOW(3, "subsys=%x, device=%x, flags=%" B_PRIx32 + ", manual_auto_sense=%d", request->subsys_status, + request->device_status, request->flags, device->manual_autosense); } if (do_autosense) { @@ -397,8 +397,10 @@ scsi_async_io(scsi_ccb *request) //snooze( 1000000 ); // do some sanity tests first - if (request->state != SCSI_STATE_FINISHED) - panic("Passed ccb to scsi_action that isn't ready (state = %d)\n", request->state); + if (request->state != SCSI_STATE_FINISHED) { + panic("Passed ccb to scsi_action that isn't ready (state = %d)\n", + request->state); + } if (request->cdb_length < func_group_len[request->cdb[0] >> 5]) { SHOW_ERROR(3, "invalid command len (%d instead of %d)", @@ -418,8 +420,8 @@ scsi_async_io(scsi_ccb *request) if ((request->flags & SCSI_DIR_MASK) != SCSI_DIR_NONE && request->sg_list == NULL && request->data_length > 0) { - SHOW_ERROR( 3, "Asynchronous SCSI I/O requires S/G list (data is %d bytes)", - (int)request->data_length ); + SHOW_ERROR( 3, "Asynchronous SCSI I/O requires S/G list (data is %" + B_PRIu32 " bytes)", request->data_length ); request->subsys_status = SCSI_DATA_RUN_ERR; goto err; } diff --git a/src/add-ons/kernel/bus_managers/scsi/virtual_memory.cpp b/src/add-ons/kernel/bus_managers/scsi/virtual_memory.cpp index 3dd7b8d129..aecdbf7132 100644 --- a/src/add-ons/kernel/bus_managers/scsi/virtual_memory.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/virtual_memory.cpp @@ -32,8 +32,9 @@ get_iovec_memory_map(iovec *vec, size_t vec_count, size_t vec_offset, size_t len size_t cur_idx; size_t left_len; - SHOW_FLOW(3, "vec_count=%lu, vec_offset=%lu, len=%lu, max_entries=%lu", - vec_count, vec_offset, len, max_entries); + SHOW_FLOW(3, "vec_count=%" B_PRIuSIZE ", vec_offset=%" B_PRIuSIZE ", len=%" + B_PRIuSIZE ", max_entries=%" B_PRIuSIZE, vec_count, vec_offset, len, + max_entries); // skip iovec blocks if needed while (vec_count > 0 && vec_offset > vec->iov_len) { @@ -117,8 +118,8 @@ get_iovec_memory_map(iovec *vec, size_t vec_count, size_t vec_offset, size_t len *num_entries = cur_idx; *mapped_len = len - left_len; - SHOW_FLOW( 3, "num_entries=%d, mapped_len=%x", - (int)*num_entries, (int)*mapped_len ); + SHOW_FLOW( 3, "num_entries=%" B_PRIuSIZE ", mapped_len=%" B_PRIxSIZE, + *num_entries, *mapped_len); return B_OK; } diff --git a/src/add-ons/kernel/bus_managers/scsi/wrapper.h b/src/add-ons/kernel/bus_managers/scsi/wrapper.h index 22381df073..0265b5c089 100644 --- a/src/add-ons/kernel/bus_managers/scsi/wrapper.h +++ b/src/add-ons/kernel/bus_managers/scsi/wrapper.h @@ -87,4 +87,4 @@ dprintf( "%s%s: "format"\n", FUNC_NAME); DEBUG_WAIT_ERROR \ }} while( 0 ) -#endif /* _BENAPHORE_H */ +#endif /* _WRAPPER_H */ diff --git a/src/add-ons/kernel/bus_managers/virtio/Jamfile b/src/add-ons/kernel/bus_managers/virtio/Jamfile new file mode 100644 index 0000000000..ef44b0043a --- /dev/null +++ b/src/add-ons/kernel/bus_managers/virtio/Jamfile @@ -0,0 +1,10 @@ +SubDir HAIKU_TOP src add-ons kernel bus_managers virtio ; + +UsePrivateHeaders virtio ; +UsePrivateKernelHeaders ; + +KernelAddon virtio : + VirtioDevice.cpp + VirtioModule.cpp + VirtioQueue.cpp + ; diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp b/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp new file mode 100644 index 0000000000..606c77ef48 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp @@ -0,0 +1,255 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include "VirtioPrivate.h" + + +const char * +virtio_get_feature_name(uint32 feature) +{ + switch (feature) { + case VIRTIO_FEATURE_NOTIFY_ON_EMPTY: + return "notify on empty"; + case VIRTIO_FEATURE_RING_INDIRECT_DESC: + return "ring indirect"; + case VIRTIO_FEATURE_RING_EVENT_IDX: + return "ring event index"; + case VIRTIO_FEATURE_BAD_FEATURE: + return "bad feature"; + } + return NULL; +} + + +const char * +virtio_get_device_type_name(uint16 type) +{ + switch (type) { + case VIRTIO_DEVICE_ID_NETWORK: + return "network"; + case VIRTIO_DEVICE_ID_BLOCK: + return "block"; + case VIRTIO_DEVICE_ID_CONSOLE: + return "console"; + case VIRTIO_DEVICE_ID_ENTROPY: + return "entropy"; + case VIRTIO_DEVICE_ID_BALLOON: + return "balloon"; + case VIRTIO_DEVICE_ID_IOMEMORY: + return "io_memory"; + case VIRTIO_DEVICE_ID_SCSI: + return "scsi"; + case VIRTIO_DEVICE_ID_9P: + return "9p transport"; + default: + return "unknown"; + } +} + + +VirtioDevice::VirtioDevice(device_node *node) + : + fNode(node), + fID(0), + fController(NULL), + fCookie(NULL), + fStatus(B_NO_INIT), + fQueues(NULL), + fFeatures(0) +{ + device_node *parent = gDeviceManager->get_parent_node(node); + fStatus = gDeviceManager->get_driver(parent, + (driver_module_info **)&fController, &fCookie); + gDeviceManager->put_node(parent); + + if (fStatus != B_OK) + return; + + fStatus = gDeviceManager->get_attr_uint16(fNode, + VIRTIO_VRING_ALIGNMENT_ITEM, &fAlignment, true); + if (fStatus != B_OK) { + ERROR("alignment missing\n"); + return; + } + + fController->set_sim(fCookie, this); + + fController->set_status(fCookie, VIRTIO_CONFIG_STATUS_DRIVER); +} + + +VirtioDevice::~VirtioDevice() +{ + for (size_t index = 0; index < fQueueCount; index++) { + delete fQueues[index]; + } + delete fQueues; +} + + +status_t +VirtioDevice::InitCheck() +{ + return fStatus; +} + + +status_t +VirtioDevice::NegociateFeatures(uint32 supported, uint32* negociated, + const char* (*get_feature_name)(uint32)) +{ + fFeatures = 0; + status_t status = fController->read_host_features(fCookie, &fFeatures); + if (status != B_OK) + return status; + + DumpFeatures("read features", fFeatures, get_feature_name); + + fFeatures &= supported; + + // filter our own features + fFeatures &= (VIRTIO_FEATURE_TRANSPORT_MASK + /*| VIRTIO_FEATURE_RING_INDIRECT_DESC*/ | VIRTIO_FEATURE_RING_EVENT_IDX); + + *negociated = fFeatures; + + DumpFeatures("negociated features", fFeatures, get_feature_name); + + return fController->write_guest_features(fCookie, fFeatures); +} + + +status_t +VirtioDevice::ReadDeviceConfig(uint8 offset, void* buffer, size_t bufferSize) +{ + return fController->read_device_config(fCookie, offset, buffer, + bufferSize); +} + + +status_t +VirtioDevice::WriteDeviceConfig(uint8 offset, const void* buffer, + size_t bufferSize) +{ + return fController->write_device_config(fCookie, offset, buffer, + bufferSize); +} + + +status_t +VirtioDevice::AllocateQueues(size_t count, virtio_queue *queues) +{ + if (count > VIRTIO_VIRTQUEUES_MAX_COUNT || queues == NULL) + return B_BAD_VALUE; + + status_t status = B_OK; + fQueues = new(std::nothrow) VirtioQueue*[count]; + if (fQueues == NULL) { + status = B_NO_MEMORY; + goto err; + } + + fQueueCount = count; + for (size_t index = 0; index < count; index++) { + uint16 size = fController->get_queue_ring_size(fCookie, index); + fQueues[index] = new(std::nothrow) VirtioQueue(this, index, size); + queues[index] = fQueues[index]; + status = B_NO_MEMORY; + if (fQueues[index] != NULL) + status = fQueues[index]->InitCheck(); + if (status != B_OK) + goto err; + } + + return B_OK; + +err: + return status; +} + + +status_t +VirtioDevice::SetupInterrupt(virtio_intr_func configHandler, + void* configCookie) +{ + fConfigHandler = configHandler; + fConfigCookie = configCookie; + status_t status = fController->setup_interrupt(fCookie); + if (status != B_OK) + return status; + + // ready to go + fController->set_status(fCookie, VIRTIO_CONFIG_STATUS_DRIVER_OK); + + for (size_t index = 0; index < fQueueCount; index++) + fQueues[index]->EnableInterrupt(); + return B_OK; +} + + +status_t +VirtioDevice::SetupQueue(uint16 queueNumber, phys_addr_t physAddr) +{ + return fController->setup_queue(fCookie, queueNumber, physAddr); +} + + +void +VirtioDevice::NotifyQueue(uint16 queueNumber) +{ + fController->notify_queue(fCookie, queueNumber); +} + + +status_t +VirtioDevice::QueueInterrupt(uint16 queueNumber) +{ + if (queueNumber != INT16_MAX) { + if (queueNumber >= fQueueCount) + return B_BAD_VALUE; + return fQueues[queueNumber]->Interrupt(); + } + + status_t status = B_OK; + for (uint16 i = 0; i < fQueueCount; i++) { + status = fQueues[i]->Interrupt(); + if (status != B_OK) + break; + } + + return status; +} + + +status_t +VirtioDevice::ConfigInterrupt() +{ + if (fConfigHandler != NULL) + fConfigHandler(fConfigCookie); + return B_OK; +} + + +void +VirtioDevice::DumpFeatures(const char* title, uint32 features, + const char* (*get_feature_name)(uint32)) +{ + char features_string[512] = ""; + for (uint32 i = 0; i < 32; i++) { + uint32 feature = features & (1 << i); + if (feature == 0) + continue; + const char* name = virtio_get_feature_name(feature); + if (name == NULL) + name = get_feature_name(feature); + if (name != NULL) { + snprintf(features_string, sizeof(features_string), "%s[%s] ", + features_string, name); + } + } + TRACE("%s: %s\n", title, features_string); +} + diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp b/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp new file mode 100644 index 0000000000..8229fc7e8c --- /dev/null +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp @@ -0,0 +1,258 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include "VirtioPrivate.h" + + +device_manager_info *gDeviceManager = NULL; + + +// #pragma mark - + + +static status_t +virtio_device_init(device_node *node, void **cookie) +{ + CALLED(); + VirtioDevice *device = new(std::nothrow) VirtioDevice(node); + if (device == NULL) + return B_NO_MEMORY; + + status_t result = device->InitCheck(); + if (result != B_OK) { + ERROR("failed to set up virtio device object\n"); + return result; + } + + *cookie = device; + return B_OK; +} + + +static void +virtio_device_uninit(void *cookie) +{ + CALLED(); + VirtioDevice *device = (VirtioDevice *)cookie; + delete device; +} + + +static void +virtio_device_removed(void *cookie) +{ + CALLED(); + //VirtioDevice *device = (VirtioDevice *)cookie; +} + + +// #pragma mark - + + +status_t +virtio_negociate_features(void* cookie, uint32 supported, + uint32* negociated, const char* (*get_feature_name)(uint32)) +{ + CALLED(); + VirtioDevice *device = (VirtioDevice *)cookie; + + return device->NegociateFeatures(supported, negociated, get_feature_name); +} + + +status_t +virtio_read_device_config(void* cookie, uint8 offset, void* buffer, + size_t bufferSize) +{ + CALLED(); + VirtioDevice *device = (VirtioDevice *)cookie; + + return device->ReadDeviceConfig(offset, buffer, bufferSize); +} + + +status_t +virtio_write_device_config(void* cookie, uint8 offset, + const void* buffer, size_t bufferSize) +{ + CALLED(); + VirtioDevice *device = (VirtioDevice *)cookie; + + return device->WriteDeviceConfig(offset, buffer, bufferSize); +} + + +status_t +virtio_alloc_queues(virtio_device cookie, size_t count, virtio_queue *queues) +{ + CALLED(); + VirtioDevice *device = (VirtioDevice *)cookie; + return device->AllocateQueues(count, queues); +} + + +status_t +virtio_setup_interrupt(virtio_device cookie, virtio_intr_func config_handler, + void* configCookie) +{ + CALLED(); + VirtioDevice *device = (VirtioDevice *)cookie; + return device->SetupInterrupt(config_handler, configCookie); +} + + +status_t +virtio_queue_request_v(virtio_queue cookie, const physical_entry* vector, + size_t readVectorCount, size_t writtenVectorCount, + virtio_callback_func callback, void *callbackCookie) +{ + CALLED(); + VirtioQueue *queue = (VirtioQueue *)cookie; + return queue->QueueRequest(vector, readVectorCount, writtenVectorCount, + callback, callbackCookie); +} + + +status_t +virtio_queue_request(virtio_queue cookie, const physical_entry *readEntry, + const physical_entry *writtenEntry, virtio_callback_func callback, + void *callbackCookie) +{ + physical_entry entries[2]; + if (readEntry != NULL) { + entries[0] = *readEntry; + if (writtenEntry != NULL) + entries[1] = *writtenEntry; + } else if (writtenEntry != NULL) + entries[0] = *writtenEntry; + + return virtio_queue_request_v(cookie, entries, readEntry != NULL ? 1 : 0, + writtenEntry != NULL? 1 : 0, callback, callbackCookie); +} + + +// #pragma mark - + + +status_t +virtio_added_device(device_node *parent) +{ + CALLED(); + + uint16 deviceType; + if (gDeviceManager->get_attr_uint16(parent, + VIRTIO_DEVICE_TYPE_ITEM, &deviceType, true) != B_OK) { + ERROR("device type missing\n"); + return B_ERROR; + } + + device_attr attributes[] = { + // info about device + { B_DEVICE_BUS, B_STRING_TYPE, { string: "virtio" }}, + { VIRTIO_DEVICE_TYPE_ITEM, B_UINT16_TYPE, + { ui16: deviceType }}, + { NULL } + }; + + return gDeviceManager->register_node(parent, VIRTIO_DEVICE_MODULE_NAME, + attributes, NULL, NULL); +} + + +status_t +virtio_queue_interrupt_handler(virtio_sim sim, uint16 queue) +{ + VirtioDevice* device = (VirtioDevice*)sim; + return device->QueueInterrupt(queue); +} + + +status_t +virtio_config_interrupt_handler(virtio_sim sim) +{ + VirtioDevice* device = (VirtioDevice*)sim; + return device->ConfigInterrupt(); +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + case B_MODULE_UNINIT: + return B_OK; + + default: + break; + } + + return B_ERROR; +} + + +// #pragma mark - + + +virtio_device_interface virtio_device_module = { + { + { + VIRTIO_DEVICE_MODULE_NAME, + 0, + std_ops + }, + + NULL, // supported devices + NULL, // register node + virtio_device_init, + virtio_device_uninit, + NULL, // register child devices + NULL, // rescan + virtio_device_removed, + NULL, // suspend + NULL, // resume + }, + + virtio_negociate_features, + virtio_read_device_config, + virtio_write_device_config, + virtio_alloc_queues, + virtio_setup_interrupt, + virtio_queue_request, + virtio_queue_request_v +}; + +virtio_for_controller_interface virtio_for_controller_module = { + { + { + VIRTIO_FOR_CONTROLLER_MODULE_NAME, + 0, + &std_ops + }, + + NULL, // supported devices + virtio_added_device, + NULL, + NULL, + NULL + }, + + virtio_queue_interrupt_handler, + virtio_config_interrupt_handler +}; + + +module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager }, + {} +}; + +module_info *modules[] = { + (module_info *)&virtio_for_controller_module, + (module_info *)&virtio_device_module, + NULL +}; + diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h b/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h new file mode 100644 index 0000000000..1b312015f9 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h @@ -0,0 +1,146 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ +#ifndef VIRTIO_PRIVATE_H +#define VIRTIO_PRIVATE_H + + +#include +#include +#include + +#include +#include +#include + +#include "virtio_ring.h" + + +//#define VIRTIO_TRACE +#ifdef VIRTIO_TRACE +# define TRACE(x...) dprintf("\33[33mvirtio:\33[0m " x) +#else +# define TRACE(x...) +#endif +#define ERROR(x...) dprintf("\33[33mvirtio:\33[0m " x) +#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) + + +#define VIRTIO_SIM_MODULE_NAME "bus_managers/virtio/sim/driver_v1" + + +class VirtioDevice; +class VirtioQueue; + +extern device_manager_info *gDeviceManager; + + +class VirtioDevice { +public: + VirtioDevice(device_node *node); + ~VirtioDevice(); + + status_t InitCheck(); + uint32 ID() const { return fID; } + + status_t NegociateFeatures(uint32 supported, + uint32* negociated, + const char* (*get_feature_name)(uint32)); + + status_t ReadDeviceConfig(uint8 offset, void* buffer, + size_t bufferSize); + status_t WriteDeviceConfig(uint8 offset, + const void* buffer, size_t bufferSize); + + status_t AllocateQueues(size_t count, + virtio_queue *queues); + status_t SetupInterrupt(virtio_intr_func config_handler, + void* configCookie); + + uint16 Alignment() { return fAlignment; } + uint32 Features() { return fFeatures; } + + status_t SetupQueue(uint16 queueNumber, + phys_addr_t physAddr); + void NotifyQueue(uint16 queueNumber); + + status_t QueueInterrupt(uint16 queueNumber); + status_t ConfigInterrupt(); + +private: + void DumpFeatures(const char* title, + uint32 features, + const char* (*get_feature_name)(uint32)); + + + device_node * fNode; + uint32 fID; + virtio_sim_interface *fController; + void * fCookie; + status_t fStatus; + VirtioQueue** fQueues; + size_t fQueueCount; + uint32 fFeatures; + uint16 fAlignment; + + virtio_intr_func fConfigHandler; + void* fConfigCookie; +}; + + +class TransferDescriptor; + + +class VirtioQueue { +public: + VirtioQueue(VirtioDevice *device, + uint16 queueNumber, uint16 ringSize); + ~VirtioQueue(); + status_t InitCheck() { return fStatus; } + + void NotifyHost(); + status_t Interrupt(); + + bool IsFull() { return fRingFree == 0; } + bool IsEmpty() { return fRingFree == fRingSize; } + + status_t QueueRequest(const physical_entry* vector, + size_t readVectorCount, + size_t writtenVectorCount, + virtio_callback_func callback, + void *callbackCookie); + status_t QueueRequestIndirect( + const physical_entry* vector, + size_t readVectorCount, + size_t writtenVectorCount, + virtio_callback_func callback, + void *callbackCookie); + void EnableInterrupt(); + void DisableInterrupt(); + +private: + void UpdateAvailable(uint16 index); + uint16 QueueVector(uint16 insertIndex, + struct vring_desc *desc, + const physical_entry* vector, + size_t readVectorCount, + size_t writtenVectorCount); + void Finish(); + + VirtioDevice* fDevice; + uint16 fQueueNumber; + uint16 fRingSize; + uint16 fRingFree; + + struct vring fRing; + uint16 fRingHeadIndex; + uint16 fRingUsedIndex; + status_t fStatus; + size_t fAreaSize; + area_id fArea; + + TransferDescriptor** fDescriptors; +}; + +#endif // VIRTIO_PRIVATE_H diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp b/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp new file mode 100644 index 0000000000..5133348170 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp @@ -0,0 +1,289 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include "VirtioPrivate.h" + + +static inline uint32 +round_to_pagesize(uint32 size) +{ + return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); +} + + +area_id +alloc_mem(void **virt, phys_addr_t *phy, size_t size, uint32 protection, + const char *name) +{ + physical_entry pe; + void * virtadr; + area_id areaid; + status_t rv; + + TRACE("allocating %ld bytes for %s\n", size, name); + + size = round_to_pagesize(size); + areaid = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size, + B_CONTIGUOUS, protection); + if (areaid < B_OK) { + ERROR("couldn't allocate area %s\n", name); + return B_ERROR; + } + rv = get_memory_map(virtadr, size, &pe, 1); + if (rv < B_OK) { + delete_area(areaid); + ERROR("couldn't get mapping for %s\n", name); + return B_ERROR; + } + if (virt) + *virt = virtadr; + if (phy) + *phy = pe.address; + TRACE("area = %" B_PRId32 ", size = %ld, virt = %p, phy = %#" B_PRIxPHYSADDR "\n", + areaid, size, virtadr, pe.address); + return areaid; +} + + +class TransferDescriptor { +public: + TransferDescriptor(uint16 size, + virtio_callback_func callback, + void *callbackCookie); + ~TransferDescriptor(); + + void Callback(); + uint16 Size() { return fDescriptorCount; } +private: + void* fCookie; + virtio_callback_func fCallback; + struct vring_desc* fIndirect; + size_t fAreaSize; + area_id fArea; + uint16 fDescriptorCount; +}; + + +TransferDescriptor::TransferDescriptor(uint16 size, + virtio_callback_func callback, void *callbackCookie) + : fCookie(callbackCookie), + fCallback(callback), + fDescriptorCount(size) +{ +} + + +TransferDescriptor::~TransferDescriptor() +{ +} + + +void +TransferDescriptor::Callback() +{ + if (fCallback != NULL) + fCallback(fCookie); +} + + +// #pragma mark - + + +VirtioQueue::VirtioQueue(VirtioDevice* device, uint16 queueNumber, + uint16 ringSize) + : + fDevice(device), + fQueueNumber(queueNumber), + fRingSize(ringSize), + fRingFree(ringSize), + fRingHeadIndex(0), + fRingUsedIndex(0), + fStatus(B_OK) +{ + fDescriptors = new(std::nothrow) TransferDescriptor*[fRingSize]; + if (fDescriptors == NULL) { + fStatus = B_NO_MEMORY; + return; + } + + uint8* virtAddr; + phys_addr_t physAddr; + fAreaSize = vring_size(fRingSize, device->Alignment()); + fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize, 0, + "virtqueue"); + if (fArea < B_OK) { + fStatus = fArea; + return; + } + memset(virtAddr, 0, fAreaSize); + vring_init(&fRing, fRingSize, virtAddr, device->Alignment()); + + for (uint16 i = 0; i < fRingSize - 1; i++) + fRing.desc[i].next = i + 1; + fRing.desc[fRingSize - 1].next = UINT16_MAX; + + DisableInterrupt(); + + device->SetupQueue(fQueueNumber, physAddr); +} + + +VirtioQueue::~VirtioQueue() +{ + delete_area(fArea); + delete[] fDescriptors; +} + + +void +VirtioQueue::DisableInterrupt() +{ + /*if ((fDevice->Features() & VIRTIO_FEATURE_RING_EVENT_IDX) == 0) + fRing.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;*/ +} + + +void +VirtioQueue::EnableInterrupt() +{ + /*if ((fDevice->Features() & VIRTIO_FEATURE_RING_EVENT_IDX) == 0) + fRing.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;*/ +} + + +void +VirtioQueue::NotifyHost() +{ + fDevice->NotifyQueue(fQueueNumber); +} + + +status_t +VirtioQueue::Interrupt() +{ + CALLED(); + DisableInterrupt(); + + while (fRingUsedIndex != fRing.used->idx) + Finish(); + + EnableInterrupt(); + return B_OK; +} + + +void +VirtioQueue::Finish() +{ + TRACE("Finish() fRingUsedIndex: %u\n", fRingUsedIndex); + + uint16 usedIndex = fRingUsedIndex++ & (fRingSize - 1); + TRACE("Finish() usedIndex: %u\n", usedIndex); + struct vring_used_elem *element = &fRing.used->ring[usedIndex]; + uint16 descriptorIndex = element->id; + // uint32 length = element->len; + + fDescriptors[descriptorIndex]->Callback(); + uint16 size = fDescriptors[descriptorIndex]->Size(); + fRingFree += size; + size--; + + uint16 index = descriptorIndex; + while ((fRing.desc[index].flags & VRING_DESC_F_NEXT) != 0) { + index = fRing.desc[index].next; + size--; + } + + if (size > 0) + panic("VirtioQueue::Finish() descriptors left %d\n", size); + + // TODO TransferDescriptors are leaked, can't delete in interrupt handler. + + fRing.desc[index].next = fRingHeadIndex; + fRingHeadIndex = descriptorIndex; + TRACE("Finish() fRingHeadIndex: %u\n", fRingHeadIndex); +} + + +status_t +VirtioQueue::QueueRequest(const physical_entry* vector, size_t readVectorCount, + size_t writtenVectorCount, virtio_callback_func callback, + void *callbackCookie) +{ + CALLED(); + size_t count = readVectorCount + writtenVectorCount; + if (count < 1) + return B_BAD_VALUE; + if ((fDevice->Features() & VIRTIO_FEATURE_RING_INDIRECT_DESC) != 0) { + return QueueRequestIndirect(vector, readVectorCount, + writtenVectorCount, callback, callbackCookie); + } + + if (count > fRingFree) + return B_BUSY; + + uint16 insertIndex = fRingHeadIndex; + fDescriptors[insertIndex] = new(std::nothrow) TransferDescriptor(count, + callback, callbackCookie); + if (fDescriptors[insertIndex] == NULL) + return B_NO_MEMORY; + + // enqueue + uint16 index = QueueVector(insertIndex, fRing.desc, vector, + readVectorCount, writtenVectorCount); + + fRingHeadIndex = index; + fRingFree -= count; + + UpdateAvailable(insertIndex); + + NotifyHost(); + + return B_OK; +} + + +status_t +VirtioQueue::QueueRequestIndirect(const physical_entry* vector, + size_t readVectorCount, size_t writtenVectorCount, + virtio_callback_func callback, void *callbackCookie) +{ + // TODO + return B_OK; +} + + +void +VirtioQueue::UpdateAvailable(uint16 index) +{ + CALLED(); + uint16 available = fRing.avail->idx & (fRingSize - 1); + fRing.avail->ring[available] = index; + fRing.avail->idx++; +} + + +uint16 +VirtioQueue::QueueVector(uint16 insertIndex, struct vring_desc *desc, + const physical_entry* vector, size_t readVectorCount, + size_t writtenVectorCount) +{ + CALLED(); + uint16 index = insertIndex; + size_t total = readVectorCount + writtenVectorCount; + for (size_t i = 0; i < total; i++) { + desc[index].addr = vector[i].address; + desc[index].len = vector[i].size; + desc[index].flags = 0; + if (i >= readVectorCount) + desc[index].flags |= VRING_DESC_F_WRITE; + if (i < total - 1) + desc[index].flags |= VRING_DESC_F_NEXT; + index = desc[index].next; + } + + return index; +} diff --git a/src/add-ons/kernel/bus_managers/virtio/virtio_ring.h b/src/add-ons/kernel/bus_managers/virtio/virtio_ring.h new file mode 100644 index 0000000000..c4f2b7313a --- /dev/null +++ b/src/add-ons/kernel/bus_managers/virtio/virtio_ring.h @@ -0,0 +1,165 @@ +/*- + * Copyright Rusty Russell IBM Corporation 2007. + * + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * 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. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM 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. + * + * $FreeBSD$ + */ + +#ifndef VIRTIO_RING_H +#define VIRTIO_RING_H + +/* This marks a buffer as continuing via the next field. */ +#define VRING_DESC_F_NEXT 1 +/* This marks a buffer as write-only (otherwise read-only). */ +#define VRING_DESC_F_WRITE 2 +/* This means the buffer contains a list of buffer descriptors. */ +#define VRING_DESC_F_INDIRECT 4 + +/* The Host uses this in used->flags to advise the Guest: don't kick me + * when you add a buffer. It's unreliable, so it's simply an + * optimization. Guest will still kick if it's out of buffers. */ +#define VRING_USED_F_NO_NOTIFY 1 +/* The Guest uses this in avail->flags to advise the Host: don't + * interrupt me when you consume a buffer. It's unreliable, so it's + * simply an optimization. */ +#define VRING_AVAIL_F_NO_INTERRUPT 1 + +/* VirtIO ring descriptors: 16 bytes. + * These can chain together via "next". */ +struct vring_desc { + /* Address (guest-physical). */ + uint64_t addr; + /* Length. */ + uint32_t len; + /* The flags as indicated above. */ + uint16_t flags; + /* We chain unused descriptors via this, too. */ + uint16_t next; +}; + +struct vring_avail { + uint16_t flags; + uint16_t idx; + uint16_t ring[0]; +}; + +/* uint32_t is used here for ids for padding reasons. */ +struct vring_used_elem { + /* Index of start of used descriptor chain. */ + uint32_t id; + /* Total length of the descriptor chain which was written to. */ + uint32_t len; +}; + +struct vring_used { + uint16_t flags; + uint16_t idx; + struct vring_used_elem ring[0]; +}; + +struct vring { + unsigned int num; + + struct vring_desc *desc; + struct vring_avail *avail; + struct vring_used *used; +}; + +/* The standard layout for the ring is a continuous chunk of memory which + * looks like this. We assume num is a power of 2. + * + * struct vring { + * // The actual descriptors (16 bytes each) + * struct vring_desc desc[num]; + * + * // A ring of available descriptor heads with free-running index. + * __u16 avail_flags; + * __u16 avail_idx; + * __u16 available[num]; + * __u16 used_event_idx; + * + * // Padding to the next align boundary. + * char pad[]; + * + * // A ring of used descriptor heads with free-running index. + * __u16 used_flags; + * __u16 used_idx; + * struct vring_used_elem used[num]; + * __u16 avail_event_idx; + * }; + * + * NOTE: for VirtIO PCI, align is 4096. + */ + +/* + * We publish the used event index at the end of the available ring, and vice + * versa. They are at the end for backwards compatibility. + */ +#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) +#define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num]) + +static inline int +vring_size(unsigned int num, unsigned long align) +{ + int size; + + size = num * sizeof(struct vring_desc); + size += sizeof(struct vring_avail) + (num * sizeof(uint16_t)) + + sizeof(uint16_t); + size = (size + align - 1) & ~(align - 1); + size += sizeof(struct vring_used) + + (num * sizeof(struct vring_used_elem)) + sizeof(uint16_t); + return (size); +} + +static inline void +vring_init(struct vring *vr, unsigned int num, uint8_t *p, + unsigned long align) +{ + vr->num = num; + vr->desc = (struct vring_desc *) p; + vr->avail = (struct vring_avail *) (p + + num * sizeof(struct vring_desc)); + vr->used = (struct vring_used *) + (((addr_t) &vr->avail->ring[num] + align-1) & ~(align-1)); +} + +/* + * The following is used with VIRTIO_RING_F_EVENT_IDX. + * + * Assuming a given event_idx value from the other size, if we have + * just incremented index from old to new_idx, should we trigger an + * event? + */ +static inline int +vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old) +{ + + return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old); +} +#endif /* VIRTIO_RING_H */ diff --git a/src/add-ons/kernel/busses/Jamfile b/src/add-ons/kernel/busses/Jamfile index 7f3e607e7b..2c9ee48853 100644 --- a/src/add-ons/kernel/busses/Jamfile +++ b/src/add-ons/kernel/busses/Jamfile @@ -10,3 +10,4 @@ if $(HAIKU_ATA_STACK) = 1 { SubInclude HAIKU_TOP src add-ons kernel busses agp_gart ; SubInclude HAIKU_TOP src add-ons kernel busses scsi ; SubInclude HAIKU_TOP src add-ons kernel busses usb ; +SubInclude HAIKU_TOP src add-ons kernel busses virtio ; diff --git a/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp b/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp index 77c6ff288e..da940836ec 100644 --- a/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp +++ b/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp @@ -108,7 +108,7 @@ struct intel_info { uint32 type; uint32 *gtt_base; - addr_t gtt_physical_base; + phys_addr_t gtt_physical_base; area_id gtt_area; size_t gtt_entries; size_t gtt_stolen_entries; @@ -117,7 +117,7 @@ struct intel_info { area_id registers_area; addr_t aperture_base; - addr_t aperture_physical_base; + phys_addr_t aperture_physical_base; area_id aperture_area; size_t aperture_size; size_t aperture_stolen_size; @@ -439,7 +439,7 @@ intel_map(intel_info &info) info.gtt_entries = gttSize / 4096; info.gtt_stolen_entries = stolenSize / 4096; - TRACE("GTT base %lx, size %lu, entries %lu, stolen %lu\n", + TRACE("GTT base %" B_PRIxPHYSADDR ", size %lu, entries %lu, stolen %lu\n", info.gtt_physical_base, gttSize, info.gtt_entries, stolenSize); AreaKeeper gttMapper; @@ -460,10 +460,12 @@ intel_map(intel_info &info) "size %ld MB, GTT size %ld KB\n", (stolenSize + (1023 << 10)) >> 20, info.aperture_size >> 20, gttSize >> 10); - dprintf("intel_gart: GTT base = 0x%lx\n", info.gtt_physical_base); - dprintf("intel_gart: MMIO base = 0x%lx\n", + dprintf("intel_gart: GTT base = 0x%" B_PRIxPHYSADDR "\n", + info.gtt_physical_base); + dprintf("intel_gart: MMIO base = 0x%" B_PRIx32 "\n", info.display.u.h0.base_registers[mmioIndex]); - dprintf("intel_gart: GMR base = 0x%lx\n", info.aperture_physical_base); + dprintf("intel_gart: GMR base = 0x%" B_PRIxPHYSADDR "\n", + info.aperture_physical_base); AreaKeeper apertureMapper; info.aperture_area = apertureMapper.Map("intel graphics aperture", @@ -606,8 +608,6 @@ intel_init() if (get_module(B_PCI_MODULE_NAME, (module_info**)&sPCI) != B_OK) return B_ERROR; - bool found = false; - for (uint32 index = 0; sPCI->get_nth_pci_info(index, &sInfo.bridge) == B_OK; index++) { if (sInfo.bridge.vendor_id != VENDOR_ID_INTEL @@ -619,20 +619,16 @@ intel_init() / sizeof(kSupportedDevices[0]); i++) { if (sInfo.bridge.device_id == kSupportedDevices[i].bridge_id) { sInfo.type = kSupportedDevices[i].type; - found = has_display_device(sInfo.display, - kSupportedDevices[i].display_id); + if (has_display_device(sInfo.display, + kSupportedDevices[i].display_id)) { + TRACE("found intel bridge\n"); + return B_OK; + } } } - - if (found) - break; } - if (!found) - return ENODEV; - - TRACE("found intel bridge\n"); - return B_OK; + return ENODEV; } diff --git a/src/add-ons/kernel/busses/scsi/Jamfile b/src/add-ons/kernel/busses/scsi/Jamfile index 8d80bbc3bb..3b1f30f2e6 100644 --- a/src/add-ons/kernel/busses/scsi/Jamfile +++ b/src/add-ons/kernel/busses/scsi/Jamfile @@ -4,3 +4,4 @@ SubInclude HAIKU_TOP src add-ons kernel busses scsi ahci ; SubInclude HAIKU_TOP src add-ons kernel busses scsi 53c8xx ; SubInclude HAIKU_TOP src add-ons kernel busses scsi buslogic ; SubInclude HAIKU_TOP src add-ons kernel busses scsi usb ; +SubInclude HAIKU_TOP src add-ons kernel busses scsi virtio ; diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci.c b/src/add-ons/kernel/busses/scsi/ahci/ahci.c index aa9e0e33d4..761355b1d6 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci.c +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci.c @@ -179,7 +179,7 @@ register_sim(device_node *parent) { SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE, { string: AHCI_DEVICE_MODULE_NAME }}, { B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { ui32: 255 }}, - { AHCI_ID_ITEM, B_UINT32_TYPE, { ui32: id }}, + { AHCI_ID_ITEM, B_UINT32_TYPE, { ui32: (uint32)id }}, // { PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, // { string: AHCI_ID_GENERATOR }}, // { PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: id }}, diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp index e88a1a4690..ecc84d00eb 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp @@ -171,7 +171,7 @@ AHCIPort::Uninit() // disable FIS receive fRegs->cmd &= ~PORT_CMD_FER; - // wait for receive completition, up to 500ms + // wait for receive completion, up to 500ms if (wait_until_clear(&fRegs->cmd, PORT_CMD_FR, 500000) < B_OK) { TRACE("AHCIPort::Uninit port %d error FIS rx still running\n", fIndex); } @@ -179,7 +179,7 @@ AHCIPort::Uninit() // stop DMA engine fRegs->cmd &= ~PORT_CMD_ST; - // wait for DMA completition + // wait for DMA completion if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) { TRACE("AHCIPort::Uninit port %d error DMA engine still running\n", fIndex); @@ -565,9 +565,9 @@ AHCIPort::ScsiInquiry(scsi_ccb *request) sreq.set_data(&ataData, sizeof(ataData)); sreq.set_ata_cmd(fIsATAPI ? 0xa1 : 0xec); // Identify (Packet) Device ExecuteSataRequest(&sreq); - sreq.wait_for_completition(); + sreq.wait_for_completion(); - if (sreq.completition_status() & ATA_ERR) { + if (sreq.completion_status() & ATA_ERR) { TRACE("identify device failed\n"); request->subsys_status = SCSI_REQ_CMP_ERR; gSCSI->finished(request, 1); diff --git a/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp b/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp index c2750d4938..9bd871b8ed 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp @@ -182,7 +182,7 @@ sata_request::abort() void -sata_request::wait_for_completition() +sata_request::wait_for_completion() { if (fCcb) panic("wrong usage"); acquire_sem(fCompletionSem); @@ -190,7 +190,7 @@ sata_request::wait_for_completition() int -sata_request::completition_status() +sata_request::completion_status() { if (fCcb) panic("wrong usage"); return fCompletionStatus; diff --git a/src/add-ons/kernel/busses/scsi/ahci/sata_request.h b/src/add-ons/kernel/busses/scsi/ahci/sata_request.h index f1efcf271f..71550f6886 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/sata_request.h +++ b/src/add-ons/kernel/busses/scsi/ahci/sata_request.h @@ -32,8 +32,8 @@ public: void finish(int tfd, size_t bytesTransfered); void abort(); - void wait_for_completition(); - int completition_status(); + void wait_for_completion(); + int completion_status(); private: scsi_ccb * fCcb; diff --git a/src/add-ons/kernel/busses/scsi/virtio/Jamfile b/src/add-ons/kernel/busses/scsi/virtio/Jamfile new file mode 100644 index 0000000000..eba2d24dd9 --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/virtio/Jamfile @@ -0,0 +1,11 @@ +SubDir HAIKU_TOP src add-ons kernel busses scsi virtio ; + +UsePrivateHeaders drivers virtio ; +UsePrivateKernelHeaders ; + +KernelAddon virtio_scsi : + virtio_scsi.cpp + VirtioSCSIController.cpp + VirtioSCSIHelper.cpp + VirtioSCSIRequest.cpp +; diff --git a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp new file mode 100644 index 0000000000..dcde6c8589 --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp @@ -0,0 +1,264 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include "VirtioSCSIPrivate.h" + +#include +#include +#include + +#include + + +const char * +get_feature_name(uint32 feature) +{ + switch (feature) { + case VIRTIO_SCSI_F_INOUT: + return "in out"; + case VIRTIO_SCSI_F_HOTPLUG: + return "hotplug"; + } + return NULL; +} + + +VirtioSCSIController::VirtioSCSIController(device_node *node) + : + fNode(node), + fVirtio(NULL), + fVirtioDevice(NULL), + fStatus(B_NO_INIT), + fRequest(NULL) +{ + CALLED(); + + B_INITIALIZE_SPINLOCK(&fInterruptLock); + fInterruptCondition.Init(this, "virtio scsi transfer"); + + // get the Virtio device from our parent's parent + device_node *parent = gDeviceManager->get_parent_node(node); + device_node *virtioParent = gDeviceManager->get_parent_node(parent); + gDeviceManager->put_node(parent); + + gDeviceManager->get_driver(virtioParent, (driver_module_info **)&fVirtio, + (void **)&fVirtioDevice); + gDeviceManager->put_node(virtioParent); + + fVirtio->negociate_features(fVirtioDevice, + 0 /*VIRTIO_SCSI_F_HOTPLUG*/, + &fFeatures, &get_feature_name); + + fStatus = fVirtio->read_device_config(fVirtioDevice, 0, &fConfig, + sizeof(struct virtio_scsi_config)); + if (fStatus != B_OK) + return; + + fConfig.sense_size = VIRTIO_SCSI_SENSE_SIZE; + fConfig.cdb_size = VIRTIO_SCSI_CDB_SIZE; + + fVirtio->write_device_config(fVirtioDevice, + offsetof(struct virtio_scsi_config, sense_size), &fConfig.sense_size, + sizeof(fConfig.sense_size)); + fVirtio->write_device_config(fVirtioDevice, + offsetof(struct virtio_scsi_config, cdb_size), &fConfig.sense_size, + sizeof(fConfig.cdb_size)); + + fRequest = new(std::nothrow) VirtioSCSIRequest(true); + if (fRequest == NULL) { + fStatus = B_NO_MEMORY; + return; + } + + ::virtio_queue virtioQueues[3]; + fStatus = fVirtio->alloc_queues(fVirtioDevice, 3, virtioQueues); + if (fStatus != B_OK) { + ERROR("queue allocation failed (%s)\n", strerror(fStatus)); + return; + } + + fControlVirtioQueue = virtioQueues[0]; + fEventVirtioQueue = virtioQueues[1]; + fRequestVirtioQueue = virtioQueues[2]; + + fStatus = fVirtio->setup_interrupt(fVirtioDevice, NULL, NULL); + if (fStatus != B_OK) { + ERROR("interrupt setup failed (%s)\n", strerror(fStatus)); + return; + } + + +} + + +VirtioSCSIController::~VirtioSCSIController() +{ + CALLED(); + delete fRequest; +} + + +status_t +VirtioSCSIController::InitCheck() +{ + return fStatus; +} + + +void +VirtioSCSIController::SetBus(scsi_bus bus) +{ + fBus = bus; +} + + +void +VirtioSCSIController::PathInquiry(scsi_path_inquiry *info) +{ + info->hba_inquiry = SCSI_PI_TAG_ABLE; + info->hba_misc = 0; + info->sim_priv = 0; + info->initiator_id = VIRTIO_SCSI_INITIATOR_ID; + info->hba_queue_size = fConfig.cmd_per_lun != 0 ? fConfig.cmd_per_lun : 1; + memset(info->vuhba_flags, 0, sizeof(info->vuhba_flags)); + + strlcpy(info->sim_vid, "Haiku", SCSI_SIM_ID); + strlcpy(info->hba_vid, "VirtIO", SCSI_HBA_ID); + + strlcpy(info->sim_version, "1.0", SCSI_VERS); + strlcpy(info->hba_version, "1.0", SCSI_VERS); + strlcpy(info->controller_family, "Virtio", SCSI_FAM_ID); + strlcpy(info->controller_type, "Virtio", SCSI_TYPE_ID); +} + + +void +VirtioSCSIController::GetRestrictions(uint8 targetID, bool *isATAPI, + bool *noAutoSense, uint32 *maxBlocks) +{ + *isATAPI = false; + *noAutoSense = true; + *maxBlocks = fConfig.cmd_per_lun; +} + + +uchar +VirtioSCSIController::ResetDevice(uchar targetID, uchar targetLUN) +{ + return SCSI_REQ_CMP; +} + + +status_t +VirtioSCSIController::ExecuteRequest(scsi_ccb *ccb) +{ + status_t result = fRequest->Start(ccb); + if (result != B_OK) + return result; + + if (ccb->cdb[0] == SCSI_OP_REQUEST_SENSE && fRequest->HasSense()) { + TRACE("request sense\n"); + fRequest->RequestSense(); + fRequest->Finish(false); + return B_OK; + } + + if (ccb->target_id > fConfig.max_target) { + ERROR("invalid target device\n"); + fRequest->SetStatus(SCSI_TID_INVALID); + fRequest->Finish(false); + return B_BAD_INDEX; + } + + if (ccb->target_lun > fConfig.max_lun) { + ERROR("invalid lun device\n"); + fRequest->SetStatus(SCSI_LUN_INVALID); + fRequest->Finish(false); + return B_BAD_INDEX; + } + + if (ccb->cdb_length > VIRTIO_SCSI_CDB_SIZE) { + fRequest->SetStatus(SCSI_REQ_INVALID); + fRequest->Finish(false); + return B_BAD_VALUE; + } + + bool isOut = (ccb->flags & SCSI_DIR_MASK) == SCSI_DIR_OUT; + bool isIn = (ccb->flags & SCSI_DIR_MASK) == SCSI_DIR_IN; + + // TODO check feature inout if request is bidirectional + + fRequest->SetTimeout(ccb->timeout > 0 ? ccb->timeout * 1000 * 1000 + : VIRTIO_SCSI_STANDARD_TIMEOUT); + + uint32 inCount = (isIn ? ccb->sg_count : 0) + 1; + uint32 outCount = (isOut ? ccb->sg_count : 0) + 1; + physical_entry entries[inCount + outCount]; + fRequest->FillRequest(inCount, outCount, entries); + + { + InterruptsSpinLocker locker(fInterruptLock); + fExpectsInterrupt = true; + fInterruptCondition.Add(&fInterruptConditionEntry); + } + + fVirtio->queue_request_v(fRequestVirtioQueue, entries, + outCount, inCount, VirtioSCSIController::RequestCallback, this); + + result = fInterruptConditionEntry.Wait(B_RELATIVE_TIMEOUT, + fRequest->Timeout()); + + { + InterruptsSpinLocker locker(fInterruptLock); + fExpectsInterrupt = false; + } + + if (result != B_OK) + return result; + + return fRequest->Finish(false); +} + + +uchar +VirtioSCSIController::AbortRequest(scsi_ccb *request) +{ + return SCSI_REQ_CMP; +} + + +uchar +VirtioSCSIController::TerminateRequest(scsi_ccb *request) +{ + return SCSI_REQ_CMP; +} + + +status_t +VirtioSCSIController::Control(uint8 targetID, uint32 op, void *buffer, + size_t length) +{ + CALLED(); + return B_DEV_INVALID_IOCTL; +} + + +void +VirtioSCSIController::RequestCallback(void* cookie) +{ + CALLED(); + VirtioSCSIController* controller = (VirtioSCSIController*)cookie; + controller->_Interrupt(); +} + + +void +VirtioSCSIController::_Interrupt() +{ + SpinLocker locker(fInterruptLock); + fInterruptCondition.NotifyAll(); +} + diff --git a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIHelper.cpp b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIHelper.cpp new file mode 100644 index 0000000000..a5ece2ae7d --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIHelper.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. + * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002/03, Thomas Kurschel. All rights reserved. + * + * Distributed under the terms of the MIT License. + */ + +#include "VirtioSCSIPrivate.h" + +#include + +#include + + +/*! Copy data between ccb data and buffer + ccb - ccb to copy data from/to + offset - offset of data in ccb + allocation_length- limit of ccb's data buffer according to CDB + buffer - data to copy data from/to + size - number of bytes to copy + to_buffer - true: copy from ccb to buffer + false: copy from buffer to ccb + return: true, if data of ccb was large enough +*/ +bool +copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength, + void *buffer, int size, bool toBuffer) +{ + const physical_entry *sgList = ccb->sg_list; + int sgCount = ccb->sg_count; + + // skip unused S/G entries + while (sgCount > 0 && offset >= sgList->size) { + offset -= sgList->size; + ++sgList; + --sgCount; + } + + if (sgCount == 0) + return false; + + // remaining bytes we are allowed to copy from/to ccb + int requestSize = MIN(allocationLength, ccb->data_length) - offset; + + // copy one S/G entry at a time + for (; size > 0 && requestSize > 0 && sgCount > 0; ++sgList, --sgCount) { + size_t bytes; + + bytes = MIN(size, requestSize); + bytes = MIN(bytes, sgList->size); + + if (toBuffer) { + vm_memcpy_from_physical(buffer, sgList->address + offset, bytes, + false); + } else { + vm_memcpy_to_physical(sgList->address + offset, buffer, bytes, + false); + } + + buffer = (char *)buffer + bytes; + size -= bytes; + offset = 0; + } + + return size == 0; +} + + +void +swap_words(void *data, size_t size) +{ + uint16 *word = (uint16 *)data; + size_t count = size / 2; + while (count--) { + *word = B_BENDIAN_TO_HOST_INT16(*word); + word++; + } +} diff --git a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIPrivate.h b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIPrivate.h new file mode 100644 index 0000000000..0dddad1fcf --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIPrivate.h @@ -0,0 +1,148 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ +#ifndef VIRTIO_SCSI_PRIVATE_H +#define VIRTIO_SCSI_PRIVATE_H + + +#include +#include +#include +#include +#include + +#include "virtio_scsi.h" + + +//#define TRACE_VIRTIO_SCSI +#ifdef TRACE_VIRTIO_SCSI +# define TRACE(x...) dprintf("virtio_scsi: " x) +#else +# define TRACE(x...) ; +#endif +#define ERROR(x...) dprintf("\33[33mvirtio_scsi:\33[0m " x) +#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) + +extern device_manager_info* gDeviceManager; +extern scsi_for_sim_interface *gSCSI; + +bool copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength, + void *buffer, int size, bool toBuffer); +void swap_words(void *data, size_t size); + + +#define VIRTIO_SCSI_STANDARD_TIMEOUT 10 * 1000 * 1000 +#define VIRTIO_SCSI_INITIATOR_ID 7 + + +class VirtioSCSIRequest; + + +class VirtioSCSIController { +public: + VirtioSCSIController(device_node* node); + ~VirtioSCSIController(); + + status_t InitCheck(); + + void SetBus(scsi_bus bus); + scsi_bus Bus() const { return fBus; } + + void PathInquiry(scsi_path_inquiry* info); + void GetRestrictions(uint8 targetID, bool* isATAPI, + bool* noAutoSense, uint32* maxBlocks); + uchar ResetDevice(uchar targetID, uchar targetLUN); + status_t ExecuteRequest(scsi_ccb* request); + uchar AbortRequest(scsi_ccb* request); + uchar TerminateRequest(scsi_ccb* request); + status_t Control(uint8 targetID, uint32 op, + void* buffer, size_t length); + +private: + static void RequestCallback(void *cookie); + void _Interrupt(); + + device_node* fNode; + scsi_bus fBus; + + virtio_device_interface* fVirtio; + virtio_device* fVirtioDevice; + + status_t fStatus; + struct virtio_scsi_config fConfig; + uint32 fFeatures; + ::virtio_queue fControlVirtioQueue; + ::virtio_queue fEventVirtioQueue; + ::virtio_queue fRequestVirtioQueue; + + area_id fArea; + struct virtio_scsi_event* fEvents; + + VirtioSCSIRequest* fRequest; + + spinlock fInterruptLock; + ConditionVariable fInterruptCondition; + ConditionVariableEntry fInterruptConditionEntry; + bool fExpectsInterrupt; + +}; + + +class VirtioSCSIRequest { +public: + VirtioSCSIRequest(bool hasLock); + ~VirtioSCSIRequest(); + + void SetStatus(uint8 status); + uint8 Status() const { return fStatus; } + + void SetTimeout(bigtime_t timeout); + bigtime_t Timeout() const { return fTimeout; } + + bool HasSense() { + return (fResponse->sense_len > 0); } + + void SetIsWrite(bool isWrite); + bool IsWrite() const { return fIsWrite; } + + void SetBytesLeft(uint32 bytesLeft); + size_t* BytesLeft() { return &fBytesLeft; } + + bool HasData() const + { return fCCB->data_length > 0; } + + status_t Finish(bool resubmit); + + // SCSI stuff + status_t Start(scsi_ccb *ccb); + scsi_ccb* CCB() { return fCCB; } + + void RequestSense(); + + void FillRequest(uint32 inCount, uint32 outCount, + physical_entry *entries); + +private: + void _FillSense(scsi_sense *sense); + uchar _ResponseStatus(); + + mutex fLock; + bool fHasLock; + + uint8 fStatus; + + bigtime_t fTimeout; + size_t fBytesLeft; + bool fIsWrite; + scsi_ccb* fCCB; + + // virtio scsi + void* fBuffer; + struct virtio_scsi_cmd_req *fRequest; + struct virtio_scsi_cmd_resp *fResponse; +}; + + +#endif // VIRTIO_SCSI_PRIVATE_H + diff --git a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIRequest.cpp b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIRequest.cpp new file mode 100644 index 0000000000..ab93b1743f --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIRequest.cpp @@ -0,0 +1,228 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. + * Distributed under the terms of the MIT License. + */ + + +#include "VirtioSCSIPrivate.h" + +#include + + +VirtioSCSIRequest::VirtioSCSIRequest(bool hasLock) + : + fHasLock(hasLock), + fTimeout(0), + fBytesLeft(0), + fIsWrite(false), + fCCB(NULL) +{ + if (hasLock) + mutex_init(&fLock, "virtio scsi request"); + + fBuffer = malloc(sizeof(struct virtio_scsi_cmd_req) + + sizeof(struct virtio_scsi_cmd_resp)); + bzero(fBuffer, sizeof(struct virtio_scsi_cmd_req) + + sizeof(struct virtio_scsi_cmd_resp)); + + fRequest = (struct virtio_scsi_cmd_req *)fBuffer; + fResponse = (struct virtio_scsi_cmd_resp *) + ((addr_t)fBuffer + sizeof(struct virtio_scsi_cmd_req)); + + fResponse->sense_len = 0; +} + + +VirtioSCSIRequest::~VirtioSCSIRequest() +{ + if (fHasLock) + mutex_destroy(&fLock); + + free(fBuffer); +} + + +void +VirtioSCSIRequest::SetStatus(uint8 status) +{ + fStatus = status; +} + + +void +VirtioSCSIRequest::SetTimeout(bigtime_t timeout) +{ + fTimeout = timeout; +} + + +void +VirtioSCSIRequest::SetIsWrite(bool isWrite) +{ + fIsWrite = isWrite; +} + + +void +VirtioSCSIRequest::SetBytesLeft(uint32 bytesLeft) +{ + fBytesLeft = bytesLeft; +} + + +status_t +VirtioSCSIRequest::Start(scsi_ccb *ccb) +{ + CALLED(); + if (mutex_trylock(&fLock) != B_OK) + return B_BUSY; + + fCCB = ccb; + fStatus = SCSI_REQ_CMP; + fCCB->device_status = SCSI_STATUS_GOOD; + fIsWrite = false; + bzero(fResponse, sizeof(struct virtio_scsi_cmd_resp)); + + TRACE("VirtioSCSIRequest::Start() opcode %x tid %x lun %x\n", ccb->cdb[0], + ccb->target_id, ccb->target_lun); + + return B_OK; +} + + +status_t +VirtioSCSIRequest::Finish(bool resubmit) +{ + CALLED(); + fStatus = _ResponseStatus(); + fCCB->data_resid = fResponse->resid; + fCCB->subsys_status = fStatus; + + TRACE("VirtioSCSIRequest::Finish() status 0x%x response 0x%x resid:0x%x" + " sense_len:%x\n", fResponse->status, fResponse->response, + fResponse->resid, fResponse->sense_len); + + if (fCCB->cdb[0] == SCSI_OP_INQUIRY) { + // when the request is an inquiry, don't do anything + } else if (fStatus == SCSI_REQ_CMP && fResponse->status != 0 + && HasSense()) { + // when the request completed and has set sense + // data, report this to the scsi stack by setting + // CHECK CONDITION status + TRACE("setting check condition\n"); + + fCCB->subsys_status = SCSI_REQ_CMP_ERR; + fCCB->device_status = SCSI_STATUS_CHECK_CONDITION; + + // copy sense data if caller requested it + if ((fCCB->flags & SCSI_DIS_AUTOSENSE) == 0) { + size_t senseLength = min_c(sizeof(fCCB->sense), + fResponse->sense_len); + memcpy(fCCB->sense, fResponse->sense, senseLength); + fCCB->sense_resid = sizeof(fCCB->sense) - senseLength; + fCCB->subsys_status |= SCSI_AUTOSNS_VALID; + } + } + + mutex_unlock(&fLock); + + if (resubmit) + gSCSI->resubmit(fCCB); + else + gSCSI->finished(fCCB, 1); + + TRACE("VirtioSCSIRequest::Finish() done\n"); + + return B_OK; +} + + +void +VirtioSCSIRequest::RequestSense() +{ + CALLED(); + // Copy sense data from last request into data buffer of current request. + // The sense data of last request is still present in the current request, + // as it isn't cleared on SCSI_OP_REQUEST_SENSE. + scsi_cmd_request_sense *command = (scsi_cmd_request_sense *)fCCB->cdb; + copy_sg_data(fCCB, 0, command->allocation_length, fResponse->sense, + fResponse->sense_len, false); + + fCCB->data_resid = fCCB->data_length - min_c(min_c(fResponse->sense_len, + command->allocation_length), fCCB->data_length); + fResponse->sense_len = 0; +} + + +void +VirtioSCSIRequest::FillRequest(uint32 inCount, uint32 outCount, + physical_entry *entries) +{ + CALLED(); + fRequest->task_attr = VIRTIO_SCSI_S_SIMPLE; + fRequest->tag = (addr_t)fCCB; + fRequest->lun[0] = 1; + fRequest->lun[1] = fCCB->target_id; + fRequest->lun[2] = 0x40 | ((fCCB->target_lun >> 8) & 0x3f); + fRequest->lun[3] = (fCCB->target_lun >> 8) & 0xff; + + memcpy(fRequest->cdb, fCCB->cdb, min_c(fCCB->cdb_length, + sizeof(fRequest->cdb))); + + get_memory_map(fBuffer, sizeof(struct virtio_scsi_cmd_req) + + sizeof(struct virtio_scsi_cmd_resp), &entries[0], 1); + entries[0].size = sizeof(struct virtio_scsi_cmd_req); + if (outCount > 1) { + memcpy(entries + 1, fCCB->sg_list, fCCB->sg_count + * sizeof(physical_entry)); + } + + entries[outCount].address = entries[0].address + + sizeof(struct virtio_scsi_cmd_req); + entries[outCount].size = sizeof(struct virtio_scsi_cmd_resp); + + if (inCount > 1) { + memcpy(entries + outCount + 1, fCCB->sg_list, fCCB->sg_count + * sizeof(physical_entry)); + } +} + + +uchar +VirtioSCSIRequest::_ResponseStatus() +{ + uchar status; + + switch (fResponse->response) { + case VIRTIO_SCSI_S_OK: + status = SCSI_REQ_CMP; + break; + case VIRTIO_SCSI_S_OVERRUN: + status = SCSI_DATA_RUN_ERR; + break; + case VIRTIO_SCSI_S_ABORTED: + status = SCSI_REQ_ABORTED; + break; + case VIRTIO_SCSI_S_BAD_TARGET: + status = SCSI_TID_INVALID; + break; + case VIRTIO_SCSI_S_RESET: + status = SCSI_SCSI_BUS_RESET; + break; + case VIRTIO_SCSI_S_BUSY: + status = SCSI_SCSI_BUSY; + break; + case VIRTIO_SCSI_S_TRANSPORT_FAILURE: + case VIRTIO_SCSI_S_TARGET_FAILURE: + case VIRTIO_SCSI_S_NEXUS_FAILURE: + status = SCSI_NO_NEXUS; + break; + default: /* VIRTIO_SCSI_S_FAILURE */ + status = SCSI_REQ_CMP_ERR; + break; + } + + return status; +} + diff --git a/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.cpp b/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.cpp new file mode 100644 index 0000000000..c1b6391179 --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.cpp @@ -0,0 +1,339 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include "VirtioSCSIPrivate.h" + +#include +#include +#include + + +#define VIRTIO_SCSI_ID_GENERATOR "virtio_scsi/id" +#define VIRTIO_SCSI_ID_ITEM "virtio_scsi/id" +#define VIRTIO_SCSI_BRIDGE_PRETTY_NAME "Virtio SCSI Bridge" +#define VIRTIO_SCSI_CONTROLLER_PRETTY_NAME "Virtio SCSI Controller" + +#define VIRTIO_SCSI_DEVICE_MODULE_NAME "busses/scsi/virtio_scsi/driver_v1" +#define VIRTIO_SCSI_SIM_MODULE_NAME "busses/scsi/virtio_scsi/sim/driver_v1" + + +device_manager_info *gDeviceManager; +scsi_for_sim_interface *gSCSI; + + +// #pragma mark - SIM module interface + + +static void +set_scsi_bus(scsi_sim_cookie cookie, scsi_bus bus) +{ + VirtioSCSIController *sim = (VirtioSCSIController *)cookie; + sim->SetBus(bus); +} + + +static void +scsi_io(scsi_sim_cookie cookie, scsi_ccb *request) +{ + CALLED(); + VirtioSCSIController *sim = (VirtioSCSIController *)cookie; + if (sim->ExecuteRequest(request) == B_BUSY) + gSCSI->requeue(request, true); +} + + +static uchar +abort_io(scsi_sim_cookie cookie, scsi_ccb *request) +{ + CALLED(); + VirtioSCSIController *sim = (VirtioSCSIController *)cookie; + return sim->AbortRequest(request); +} + + +static uchar +reset_device(scsi_sim_cookie cookie, uchar targetID, uchar targetLUN) +{ + CALLED(); + VirtioSCSIController *sim = (VirtioSCSIController *)cookie; + return sim->ResetDevice(targetID, targetLUN); +} + + +static uchar +terminate_io(scsi_sim_cookie cookie, scsi_ccb *request) +{ + CALLED(); + VirtioSCSIController *sim = (VirtioSCSIController *)cookie; + return sim->TerminateRequest(request); +} + + +static uchar +path_inquiry(scsi_sim_cookie cookie, scsi_path_inquiry *info) +{ + CALLED(); + + VirtioSCSIController *sim = (VirtioSCSIController *)cookie; + if (sim->Bus() == NULL) + return SCSI_NO_HBA; + + sim->PathInquiry(info); + return SCSI_REQ_CMP; +} + + +//! this is called immediately before the SCSI bus manager scans the bus +static uchar +scan_bus(scsi_sim_cookie cookie) +{ + CALLED(); + + return SCSI_REQ_CMP; +} + + +static uchar +reset_bus(scsi_sim_cookie cookie) +{ + CALLED(); + + return SCSI_REQ_CMP; +} + + +/*! Get restrictions of one device + (used for non-SCSI transport protocols and bug fixes) +*/ +static void +get_restrictions(scsi_sim_cookie cookie, uchar targetID, bool *isATAPI, + bool *noAutoSense, uint32 *maxBlocks) +{ + CALLED(); + VirtioSCSIController *sim = (VirtioSCSIController *)cookie; + sim->GetRestrictions(targetID, isATAPI, noAutoSense, maxBlocks); +} + + +static status_t +ioctl(scsi_sim_cookie cookie, uint8 targetID, uint32 op, void *buffer, + size_t length) +{ + CALLED(); + VirtioSCSIController *sim = (VirtioSCSIController *)cookie; + return sim->Control(targetID, op, buffer, length); +} + + +// #pragma mark - + + +static status_t +sim_init_bus(device_node *node, void **_cookie) +{ + CALLED(); + + VirtioSCSIController *controller = new(std::nothrow) + VirtioSCSIController(node); + if (controller == NULL) + return B_NO_MEMORY; + status_t status = controller->InitCheck(); + if (status < B_OK) { + delete controller; + return status; + } + + *_cookie = controller; + return B_OK; +} + + +static void +sim_uninit_bus(void *cookie) +{ + CALLED(); + VirtioSCSIController *controller = (VirtioSCSIController*)cookie; + + delete controller; +} + + +// #pragma mark - + + +static float +virtio_scsi_supports_device(device_node *parent) +{ + const char *bus; + uint16 deviceType; + + // make sure parent is really the Virtio bus manager + if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) + return -1; + + if (strcmp(bus, "virtio")) + return 0.0; + + // check whether it's really a Virtio SCSI Device + if (gDeviceManager->get_attr_uint16(parent, VIRTIO_DEVICE_TYPE_ITEM, + &deviceType, true) != B_OK || deviceType != VIRTIO_DEVICE_ID_SCSI) + return 0.0; + + TRACE("Virtio SCSI device found!\n"); + + return 0.6f; +} + + +static status_t +virtio_scsi_register_device(device_node *parent) +{ + CALLED(); + virtio_device_interface* virtio = NULL; + virtio_device* virtioDevice = NULL; + struct virtio_scsi_config config; + + gDeviceManager->get_driver(parent, (driver_module_info **)&virtio, + (void **)&virtioDevice); + + status_t status = virtio->read_device_config(virtioDevice, 0, &config, + sizeof(struct virtio_scsi_config)); + if (status != B_OK) + return status; + + uint32 max_targets = config.max_target + 1; + uint32 max_blocks = 0x10000; + if (config.max_sectors != 0) + max_blocks = config.max_sectors; + + device_attr attrs[] = { + { SCSI_DEVICE_MAX_TARGET_COUNT, B_UINT32_TYPE, + { ui32: max_targets }}, + { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, + { string: VIRTIO_SCSI_BRIDGE_PRETTY_NAME }}, + + // DMA properties + { B_DMA_MAX_SEGMENT_BLOCKS, B_UINT32_TYPE, { ui32: max_blocks }}, + { B_DMA_MAX_SEGMENT_COUNT, B_UINT32_TYPE, + { ui32: config.seg_max }}, + { NULL } + }; + + return gDeviceManager->register_node(parent, VIRTIO_SCSI_DEVICE_MODULE_NAME, + attrs, NULL, NULL); +} + + +static status_t +virtio_scsi_init_driver(device_node *node, void **_cookie) +{ + CALLED(); + *_cookie = node; + return B_OK; +} + + +static status_t +virtio_scsi_register_child_devices(void *cookie) +{ + CALLED(); + device_node *node = (device_node *)cookie; + + int32 id = gDeviceManager->create_id(VIRTIO_SCSI_ID_GENERATOR); + if (id < 0) + return id; + + device_attr attrs[] = { + { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, + { string: SCSI_FOR_SIM_MODULE_NAME }}, + { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, + { string: VIRTIO_SCSI_CONTROLLER_PRETTY_NAME }}, + { SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE, + { string: VIRTIO_SCSI_DEVICE_MODULE_NAME }}, + { B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { ui32: 255 }}, + { VIRTIO_SCSI_ID_ITEM, B_UINT32_TYPE, { ui32: (uint32)id }}, + { NULL } + }; + + status_t status = gDeviceManager->register_node(node, + VIRTIO_SCSI_SIM_MODULE_NAME, attrs, NULL, NULL); + if (status < B_OK) + gDeviceManager->free_id(VIRTIO_SCSI_ID_GENERATOR, id); + + return status; +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + case B_MODULE_UNINIT: + return B_OK; + + default: + return B_ERROR; + } +} + + +static scsi_sim_interface sVirtioSCSISimInterface = { + { + { + VIRTIO_SCSI_SIM_MODULE_NAME, + 0, + std_ops + }, + NULL, // supported devices + NULL, // register node + sim_init_bus, + sim_uninit_bus, + NULL, // register child devices + NULL, // rescan + NULL // bus_removed + }, + set_scsi_bus, + scsi_io, + abort_io, + reset_device, + terminate_io, + path_inquiry, + scan_bus, + reset_bus, + get_restrictions, + ioctl +}; + + +static driver_module_info sVirtioSCSIDevice = { + { + VIRTIO_SCSI_DEVICE_MODULE_NAME, + 0, + std_ops + }, + virtio_scsi_supports_device, + virtio_scsi_register_device, + virtio_scsi_init_driver, + NULL, // uninit_driver, + virtio_scsi_register_child_devices, + NULL, // rescan + NULL, // device_removed +}; + + +module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager }, + { SCSI_FOR_SIM_MODULE_NAME, (module_info **)&gSCSI }, + {} +}; + + +module_info *modules[] = { + (module_info *)&sVirtioSCSIDevice, + (module_info *)&sVirtioSCSISimInterface, + NULL +}; diff --git a/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.h b/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.h new file mode 100644 index 0000000000..b781839a32 --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.h @@ -0,0 +1,152 @@ +/*- + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL 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. + * + * $FreeBSD$ + */ + +#ifndef _VIRTIO_SCSI_H +#define _VIRTIO_SCSI_H + +/* Feature bits */ +#define VIRTIO_SCSI_F_INOUT 0x0001 /* Single request can contain both + * read and write buffers */ +#define VIRTIO_SCSI_F_HOTPLUG 0x0002 /* Host should enable hot plug/unplug + * of new LUNs and targets. + */ + +#define VIRTIO_SCSI_CDB_SIZE 32 +#define VIRTIO_SCSI_SENSE_SIZE 96 + +/* SCSI command request, followed by data-out */ +struct virtio_scsi_cmd_req { + uint8_t lun[8]; /* Logical Unit Number */ + uint64_t tag; /* Command identifier */ + uint8_t task_attr; /* Task attribute */ + uint8_t prio; + uint8_t crn; + uint8_t cdb[VIRTIO_SCSI_CDB_SIZE]; +} _PACKED; + +/* Response, followed by sense data and data-in */ +struct virtio_scsi_cmd_resp { + uint32_t sense_len; /* Sense data length */ + uint32_t resid; /* Residual bytes in data buffer */ + uint16_t status_qualifier; /* Status qualifier */ + uint8_t status; /* Command completion status */ + uint8_t response; /* Response values */ + uint8_t sense[VIRTIO_SCSI_SENSE_SIZE]; +} _PACKED; + +/* Task Management Request */ +struct virtio_scsi_ctrl_tmf_req { + uint32_t type; + uint32_t subtype; + uint8_t lun[8]; + uint64_t tag; +} _PACKED; + +struct virtio_scsi_ctrl_tmf_resp { + uint8_t response; +} _PACKED; + +/* Asynchronous notification query/subscription */ +struct virtio_scsi_ctrl_an_req { + uint32_t type; + uint8_t lun[8]; + uint32_t event_requested; +} _PACKED; + +struct virtio_scsi_ctrl_an_resp { + uint32_t event_actual; + uint8_t response; +} _PACKED; + +struct virtio_scsi_event { + uint32_t event; + uint8_t lun[8]; + uint32_t reason; +} _PACKED; + +struct virtio_scsi_config { + uint32_t num_queues; + uint32_t seg_max; + uint32_t max_sectors; + uint32_t cmd_per_lun; + uint32_t event_info_size; + uint32_t sense_size; + uint32_t cdb_size; + uint16_t max_channel; + uint16_t max_target; + uint32_t max_lun; +} _PACKED; + +/* Response codes */ +#define VIRTIO_SCSI_S_OK 0 +#define VIRTIO_SCSI_S_FUNCTION_COMPLETE 0 +#define VIRTIO_SCSI_S_OVERRUN 1 +#define VIRTIO_SCSI_S_ABORTED 2 +#define VIRTIO_SCSI_S_BAD_TARGET 3 +#define VIRTIO_SCSI_S_RESET 4 +#define VIRTIO_SCSI_S_BUSY 5 +#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 +#define VIRTIO_SCSI_S_TARGET_FAILURE 7 +#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 +#define VIRTIO_SCSI_S_FAILURE 9 +#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 +#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 +#define VIRTIO_SCSI_S_INCORRECT_LUN 12 + +/* Controlq type codes. */ +#define VIRTIO_SCSI_T_TMF 0 +#define VIRTIO_SCSI_T_AN_QUERY 1 +#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 + +/* Valid TMF subtypes. */ +#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 +#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 +#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 +#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 +#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 +#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 +#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 +#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 + +/* Events. */ +#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 +#define VIRTIO_SCSI_T_NO_EVENT 0 +#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 +#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 + +/* Reasons of transport reset event */ +#define VIRTIO_SCSI_EVT_RESET_HARD 0 +#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 +#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 + +#define VIRTIO_SCSI_S_SIMPLE 0 +#define VIRTIO_SCSI_S_ORDERED 1 +#define VIRTIO_SCSI_S_HEAD 2 +#define VIRTIO_SCSI_S_ACA 3 + +#endif /* _VIRTIO_SCSI_H */ diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index 0d7c2a83d2..2c6b79b882 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -118,6 +118,8 @@ EHCI::EHCI(pci_info *info, Stack *stack) fPeriodicFrameListArea(-1), fPeriodicFrameList(NULL), fInterruptEntries(NULL), + fItdEntries(NULL), + fSitdEntries(NULL), fAsyncQueueHead(NULL), fAsyncAdvanceSem(-1), fFirstTransfer(NULL), diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp index 303e165d48..f7e3a97be1 100644 --- a/src/add-ons/kernel/busses/usb/xhci.cpp +++ b/src/add-ons/kernel/busses/usb/xhci.cpp @@ -154,9 +154,10 @@ XHCI::XHCI(pci_info *info, Stack *stack) size_t mapSize = (fPCIInfo->u.h0.base_register_sizes[0] + offset + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); - TRACE("map physical memory 0x%08lx (base: 0x%08" B_PRIxPHYSADDR "; offset:" - " %lx); size: %ld\n", fPCIInfo->u.h0.base_registers[0], - physicalAddress, offset, fPCIInfo->u.h0.base_register_sizes[0]); + TRACE("map physical memory 0x%08" B_PRIx32 " (base: 0x%08" B_PRIxPHYSADDR + "; offset: %" B_PRIx32 "); size: %" B_PRId32 "\n", + fPCIInfo->u.h0.base_registers[0], physicalAddress, offset, + fPCIInfo->u.h0.base_register_sizes[0]); fRegisterArea = map_physical_memory("XHCI memory mapped registers", physicalAddress, mapSize, B_ANY_KERNEL_BLOCK_ADDRESS, @@ -169,19 +170,23 @@ XHCI::XHCI(pci_info *info, Stack *stack) uint32 hciCapLength = ReadCapReg32(XHCI_HCI_CAPLENGTH); fCapabilityRegisters += offset; - TRACE("mapped capability length: 0x%lx\n", fCapabilityLength); + TRACE("mapped capability length: 0x%" B_PRIx32 "\n", fCapabilityLength); fOperationalRegisters = fCapabilityRegisters + HCI_CAPLENGTH(hciCapLength); fRuntimeRegisters = fCapabilityRegisters + ReadCapReg32(XHCI_RTSOFF); fDoorbellRegisters = fCapabilityRegisters + ReadCapReg32(XHCI_DBOFF); - TRACE("mapped capability registers: 0x%08lx\n", (uint32)fCapabilityRegisters); - TRACE("mapped operational registers: 0x%08lx\n", (uint32)fOperationalRegisters); - TRACE("mapped runtime registers: 0x%08lx\n", (uint32)fRuntimeRegisters); - TRACE("mapped doorbell registers: 0x%08lx\n", (uint32)fDoorbellRegisters); + TRACE("mapped capability registers: 0x%p\n", fCapabilityRegisters); + TRACE("mapped operational registers: 0x%p\n", fOperationalRegisters); + TRACE("mapped runtime registers: 0x%p\n", fRuntimeRegisters); + TRACE("mapped doorbell registers: 0x%p\n", fDoorbellRegisters); - TRACE("structural parameters1: 0x%08lx\n", ReadCapReg32(XHCI_HCSPARAMS1)); - TRACE("structural parameters2: 0x%08lx\n", ReadCapReg32(XHCI_HCSPARAMS2)); - TRACE("structural parameters3: 0x%08lx\n", ReadCapReg32(XHCI_HCSPARAMS3)); - TRACE("capability parameters: 0x%08lx\n", ReadCapReg32(XHCI_HCCPARAMS)); + TRACE("structural parameters1: 0x%08" B_PRIx32 "\n", + ReadCapReg32(XHCI_HCSPARAMS1)); + TRACE("structural parameters2: 0x%08" B_PRIx32 "\n", + ReadCapReg32(XHCI_HCSPARAMS2)); + TRACE("structural parameters3: 0x%08" B_PRIx32 "\n", + ReadCapReg32(XHCI_HCSPARAMS3)); + TRACE("capability parameters: 0x%08" B_PRIx32 "\n", + ReadCapReg32(XHCI_HCCPARAMS)); uint32 cparams = ReadCapReg32(XHCI_HCCPARAMS); uint32 eec = 0xffffffff; @@ -191,7 +196,7 @@ XHCI::XHCI(pci_info *info, Stack *stack) if (XECP_ID(eec) != XHCI_LEGSUP_CAPID) continue; } - TRACE("eecp register: 0x%04lx\n", eecp); + TRACE("eecp register: 0x%04" B_PRIx32 "\n", eecp); if (eec & XHCI_LEGSUP_BIOSOWNED) { TRACE_ALWAYS("the host controller is bios owned, claiming" " ownership\n"); @@ -291,8 +296,8 @@ status_t XHCI::Start() { TRACE("starting XHCI host controller\n"); - TRACE("usbcmd: 0x%08lx; usbsts: 0x%08lx\n", ReadOpReg(XHCI_CMD), - ReadOpReg(XHCI_STS)); + TRACE("usbcmd: 0x%08" B_PRIx32 "; usbsts: 0x%08" B_PRIx32 "\n", + ReadOpReg(XHCI_CMD), ReadOpReg(XHCI_STS)); if ((ReadOpReg(XHCI_PAGESIZE) & (1 << 0)) == 0) { TRACE_ERROR("Controller does not support 4K page size.\n"); @@ -334,7 +339,7 @@ XHCI::Start() fPortSpeeds[i] = USB_SPEED_SUPER; else fPortSpeeds[i] = USB_SPEED_HIGHSPEED; - TRACE("speed for port %ld is %s\n", i, + TRACE("speed for port %" B_PRId32 " is %s\n", i, fPortSpeeds[i] == USB_SPEED_SUPER ? "super" : "high"); } portFound += count; @@ -354,8 +359,8 @@ XHCI::Start() WriteOpReg(XHCI_DNCTRL, 0); // allocate Device Context Base Address array - addr_t dmaAddress; - fDcbaArea = fStack->AllocateArea((void **)&fDcba, (void**)&dmaAddress, + phys_addr_t dmaAddress; + fDcbaArea = fStack->AllocateArea((void **)&fDcba, &dmaAddress, sizeof(*fDcba), "DCBA Area"); if (fDcbaArea < B_OK) { TRACE_ERROR("unable to create the DCBA area\n"); @@ -371,9 +376,9 @@ XHCI::Start() // fill up the scratchpad array with scratchpad pages for (uint32 i = 0; i < fScratchpadCount; i++) { - addr_t scratchDmaAddress; + phys_addr_t scratchDmaAddress; fScratchpadArea[i] = fStack->AllocateArea((void **)&fScratchpad[i], - (void**)&scratchDmaAddress, B_PAGE_SIZE, "Scratchpad Area"); + &scratchDmaAddress, B_PAGE_SIZE, "Scratchpad Area"); if (fScratchpadArea[i] < B_OK) { TRACE_ERROR("unable to create the scratchpad area\n"); return B_ERROR; @@ -381,13 +386,13 @@ XHCI::Start() fDcba->scratchpad[i] = scratchDmaAddress; } - TRACE("setting DCBAAP %lx\n", dmaAddress); + TRACE("setting DCBAAP %" B_PRIxPHYSADDR "\n", dmaAddress); WriteOpReg(XHCI_DCBAAP_LO, (uint32)dmaAddress); WriteOpReg(XHCI_DCBAAP_HI, /*(uint32)(dmaAddress >> 32)*/0); // allocate Event Ring Segment Table uint8 *addr; - fErstArea = fStack->AllocateArea((void **)&addr, (void**)&dmaAddress, + fErstArea = fStack->AllocateArea((void **)&addr, &dmaAddress, (XHCI_MAX_COMMANDS + XHCI_MAX_EVENTS) * sizeof(xhci_trb) + sizeof(xhci_erst_element), "USB XHCI ERST CMD_RING and EVENT_RING Area"); @@ -402,7 +407,7 @@ XHCI::Start() + sizeof(xhci_erst_element)); // fill with Event Ring Segment Base Address and Event Ring Segment Size - fErst->rs_addr = (uint64)(dmaAddress + sizeof(xhci_erst_element)); + fErst->rs_addr = dmaAddress + sizeof(xhci_erst_element); fErst->rs_size = XHCI_MAX_EVENTS; fErst->rsvdz = 0; @@ -414,17 +419,17 @@ XHCI::Start() TRACE("setting ERST size\n"); WriteRunReg32(XHCI_ERSTSZ(0), XHCI_ERSTS_SET(1)); - TRACE("setting ERDP addr = 0x%llx\n", fErst->rs_addr); + TRACE("setting ERDP addr = 0x%" B_PRIx64 "\n", fErst->rs_addr); WriteRunReg32(XHCI_ERDP_LO(0), (uint32)fErst->rs_addr); WriteRunReg32(XHCI_ERDP_HI(0), /*(uint32)(fErst->rs_addr >> 32)*/0); - TRACE("setting ERST base addr = 0x%lx\n", dmaAddress); + TRACE("setting ERST base addr = 0x%" B_PRIxPHYSADDR "\n", dmaAddress); WriteRunReg32(XHCI_ERSTBA_LO(0), (uint32)dmaAddress); WriteRunReg32(XHCI_ERSTBA_HI(0), /*(uint32)(dmaAddress >> 32)*/0); dmaAddress += sizeof(xhci_erst_element) + XHCI_MAX_EVENTS * sizeof(xhci_trb); - TRACE("setting CRCR addr = 0x%lx\n", dmaAddress); + TRACE("setting CRCR addr = 0x%" B_PRIxPHYSADDR "\n", dmaAddress); WriteOpReg(XHCI_CRCR_LO, (uint32)dmaAddress | CRCR_RCS); WriteOpReg(XHCI_CRCR_HI, /*(uint32)(dmaAddress >> 32)*/0); //link trb @@ -638,7 +643,8 @@ XHCI::AddTo(Stack *stack) status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); if (status < B_OK) { - TRACE_MODULE_ERROR("getting pci module failed! 0x%08lx\n", status); + TRACE_MODULE_ERROR("getting pci module failed! 0x%08" B_PRIx32 + "\n", status); return status; } } @@ -706,7 +712,8 @@ XHCI::CreateDescriptorChain(size_t bufferSize) size_t packetSize = B_PAGE_SIZE * 16; int32 trbCount = (bufferSize + packetSize - 1) / packetSize; // keep one trb for linking - int32 tdCount = (trbCount + XHCI_MAX_TRBS_PER_TD - 2) / (XHCI_MAX_TRBS_PER_TD - 1); + int32 tdCount = (trbCount + XHCI_MAX_TRBS_PER_TD - 2) + / (XHCI_MAX_TRBS_PER_TD - 1); xhci_td *first = NULL; xhci_td *last = NULL; @@ -719,13 +726,13 @@ XHCI::CreateDescriptorChain(size_t bufferSize) first = descriptor; uint8 trbs = min_c(trbCount, XHCI_MAX_TRBS_PER_TD); - TRACE("CreateDescriptorChain trbs %d for td %ld\n", trbs, i); + TRACE("CreateDescriptorChain trbs %d for td %" B_PRId32 "\n", trbs, i); for (int j = 0; j < trbs; j++) { if (fStack->AllocateChunk(&descriptor->buffer_log[j], - (void **)&descriptor->buffer_phy[j], + &descriptor->buffer_phy[j], min_c(packetSize, bufferSize)) < B_OK) { - TRACE_ERROR("unable to allocate space for the buffer (size %ld)\n", - bufferSize); + TRACE_ERROR("unable to allocate space for the buffer (size %" + B_PRIuSIZE ")\n", bufferSize); return NULL; } @@ -750,15 +757,15 @@ xhci_td * XHCI::CreateDescriptor(size_t bufferSize) { xhci_td *result; - addr_t physicalAddress; + phys_addr_t physicalAddress; - if (fStack->AllocateChunk((void **)&result, (void**)&physicalAddress, + if (fStack->AllocateChunk((void **)&result, &physicalAddress, sizeof(xhci_td)) < B_OK) { TRACE_ERROR("failed to allocate a transfer descriptor\n"); return NULL; } - result->this_phy = (addr_t)physicalAddress; + result->this_phy = physicalAddress; result->buffer_size[0] = bufferSize; result->trb_count = 0; result->buffer_count = 1; @@ -769,10 +776,10 @@ XHCI::CreateDescriptor(size_t bufferSize) } if (fStack->AllocateChunk(&result->buffer_log[0], - (void **)&result->buffer_phy[0], bufferSize) < B_OK) { + &result->buffer_phy[0], bufferSize) < B_OK) { TRACE_ERROR("unable to allocate space for the buffer (size %ld)\n", bufferSize); - fStack->FreeChunk(result, (void *)result->this_phy, sizeof(xhci_td)); + fStack->FreeChunk(result, result->this_phy, sizeof(xhci_td)); return NULL; } @@ -792,10 +799,10 @@ XHCI::FreeDescriptor(xhci_td *descriptor) TRACE("FreeDescriptor buffer %d buffer_size %ld\n", i, descriptor->buffer_size[i]); fStack->FreeChunk(descriptor->buffer_log[i], - (void *)descriptor->buffer_phy[i], descriptor->buffer_size[i]); + descriptor->buffer_phy[i], descriptor->buffer_size[i]); } - fStack->FreeChunk(descriptor, (void *)descriptor->this_phy, + fStack->FreeChunk(descriptor, descriptor->this_phy, sizeof(xhci_td)); } @@ -941,7 +948,7 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, device->slot = slot; device->input_ctx_area = fStack->AllocateArea((void **)&device->input_ctx, - (void**)&device->input_ctx_addr, sizeof(*device->input_ctx), + &device->input_ctx_addr, sizeof(*device->input_ctx), "XHCI input context"); if (device->input_ctx_area < B_OK) { TRACE_ERROR("unable to create a input context area\n"); @@ -993,14 +1000,17 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, device->input_ctx->slot.dwslot2 = SLOT_2_IRQ_TARGET(0); if (0) device->input_ctx->slot.dwslot2 |= SLOT_2_PORT_NUM(hubPort); - device->input_ctx->slot.dwslot3 = SLOT_3_SLOT_STATE(0) | SLOT_3_DEVICE_ADDRESS(0); + device->input_ctx->slot.dwslot3 = SLOT_3_SLOT_STATE(0) + | SLOT_3_DEVICE_ADDRESS(0); - TRACE("slot 0x%lx 0x%lx 0x%lx 0x%lx\n", device->input_ctx->slot.dwslot0, + TRACE("slot 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx32 + "\n", device->input_ctx->slot.dwslot0, device->input_ctx->slot.dwslot1, device->input_ctx->slot.dwslot2, device->input_ctx->slot.dwslot3); device->device_ctx_area = fStack->AllocateArea((void **)&device->device_ctx, - (void**)&device->device_ctx_addr, sizeof(*device->device_ctx), "XHCI device context"); + &device->device_ctx_addr, sizeof(*device->device_ctx), + "XHCI device context"); if (device->device_ctx_area < B_OK) { TRACE_ERROR("unable to create a device context area\n"); delete_area(device->input_ctx_area); @@ -1009,7 +1019,7 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, memset(device->device_ctx, 0, sizeof(*device->device_ctx)); device->trb_area = fStack->AllocateArea((void **)&device->trbs, - (void**)&device->trb_addr, sizeof(*device->trbs), "XHCI endpoint trbs"); + &device->trb_addr, sizeof(*device->trbs), "XHCI endpoint trbs"); if (device->trb_area < B_OK) { TRACE_ERROR("unable to create a device trbs area\n"); delete_area(device->input_ctx_area); @@ -1064,18 +1074,19 @@ XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, } device->state = XHCI_STATE_ADDRESSED; - device->address = SLOT_3_DEVICE_ADDRESS_GET(device->device_ctx->slot.dwslot3); + device->address = SLOT_3_DEVICE_ADDRESS_GET( + device->device_ctx->slot.dwslot3); - TRACE("device: address 0x%x state 0x%lx\n", device->address, + TRACE("device: address 0x%x state 0x%" B_PRIx32 "\n", device->address, SLOT_3_SLOT_STATE_GET(device->device_ctx->slot.dwslot3)); - TRACE("endpoint0 state 0x%lx\n", + TRACE("endpoint0 state 0x%" B_PRIx32 "\n", ENDPOINT_0_STATE_GET(device->device_ctx->endpoints[0].dwendpoint0)); // Create a temporary pipe with the new address ControlPipe pipe(parent); pipe.SetControllerCookie(&device->endpoints[0]); - pipe.InitCommon(device->address + 1, 0, speed, Pipe::Default, 8, 0, hubAddress, - hubPort); + pipe.InitCommon(device->address + 1, 0, speed, Pipe::Default, 8, 0, + hubAddress, hubPort); // Get the device descriptor // Just retrieve the first 8 bytes of the descriptor -> minimum supported @@ -1175,8 +1186,9 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe) TRACE("_InsertEndpointForPipe trbs device %p endpoint %p\n", device->trbs, device->endpoints[id].trbs); - TRACE("_InsertEndpointForPipe trb_addr device 0x%lx endpoint 0x%lx\n", - device->trb_addr, device->endpoints[id].trb_addr); + TRACE("_InsertEndpointForPipe trb_addr device 0x%" B_PRIxPHYSADDR + " endpoint 0x%" B_PRIxPHYSADDR "\n", device->trb_addr, + device->endpoints[id].trb_addr); uint8 endpoint = id + 1; @@ -1200,7 +1212,7 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe) type = 1; type |= (pipe->Direction() == Pipe::In) ? (1 << 2) : 0; - TRACE("trb_addr 0x%lx\n", device->endpoints[id].trb_addr); + TRACE("trb_addr 0x%" B_PRIxPHYSADDR "\n", device->endpoints[id].trb_addr); if (ConfigureEndpoint(device->slot, id, type, device->endpoints[id].trb_addr, pipe->Interval(), @@ -1213,11 +1225,11 @@ XHCI::_InsertEndpointForPipe(Pipe *pipe) EvaluateContext(device->input_ctx_addr, device->slot); ConfigureEndpoint(device->input_ctx_addr, false, device->slot); - TRACE("device: address 0x%x state 0x%lx\n", device->address, + TRACE("device: address 0x%x state 0x%" B_PRIx32 "\n", device->address, SLOT_3_SLOT_STATE_GET(device->device_ctx->slot.dwslot3)); - TRACE("endpoint[0] state 0x%lx\n", + TRACE("endpoint[0] state 0x%" B_PRIx32 "\n", ENDPOINT_0_STATE_GET(device->device_ctx->endpoints[0].dwendpoint0)); - TRACE("endpoint[%d] state 0x%lx\n", id, + TRACE("endpoint[%d] state 0x%" B_PRIx32 "\n", id, ENDPOINT_0_STATE_GET(device->device_ctx->endpoints[id].dwendpoint0)); device->state = XHCI_STATE_CONFIGURED; } @@ -1276,8 +1288,8 @@ XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) endpoint->trbs[current].dwtrb3 = TRB_3_TYPE(TRB_TYPE_LINK) | TRB_3_CYCLE_BIT; - TRACE("_LinkDescriptorForPipe pCurrent %p phys 0x%lx 0x%llx 0x%lx\n", - &endpoint->trbs[current], + TRACE("_LinkDescriptorForPipe pCurrent %p phys 0x%" B_PRIxPHYSADDR + " 0x%" B_PRIxPHYSADDR " 0x%" B_PRIx32 "\n", &endpoint->trbs[current], endpoint->trb_addr + current * sizeof(struct xhci_trb), endpoint->trbs[current].qwtrb0, endpoint->trbs[current].dwtrb3); endpoint->current = next; @@ -1368,8 +1380,9 @@ XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, u endpoint->dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(B_PAGE_SIZE); } - TRACE("endpoint 0x%lx 0x%lx 0x%llx 0x%lx\n", endpoint->dwendpoint0, - endpoint->dwendpoint1, endpoint->qwendpoint2, endpoint->dwendpoint4); + TRACE("endpoint 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx64 " 0x%" + B_PRIx32 "\n", endpoint->dwendpoint0, endpoint->dwendpoint1, + endpoint->qwendpoint2, endpoint->dwendpoint4); return B_OK; } @@ -1563,8 +1576,8 @@ XHCI::ControllerHalt() status_t XHCI::ControllerReset() { - TRACE("ControllerReset() cmd: 0x%lx sts: 0x%lx\n", ReadOpReg(XHCI_CMD), - ReadOpReg(XHCI_STS)); + TRACE("ControllerReset() cmd: 0x%" B_PRIx32 " sts: 0x%" B_PRIx32 "\n", + ReadOpReg(XHCI_CMD), ReadOpReg(XHCI_STS)); WriteOpReg(XHCI_CMD, ReadOpReg(XHCI_CMD) | CMD_HCRST); int32 tries = 250; @@ -1622,7 +1635,7 @@ XHCI::Interrupt() } if ((status & STS_EINT) == 0) { - TRACE("STS: %lx IRQ_PENDING: %lx\n", status, temp); + TRACE("STS: %" B_PRIx32 " IRQ_PENDING: %" B_PRIx32 "\n", status, temp); return B_UNHANDLED_INTERRUPT; } @@ -1656,8 +1669,8 @@ XHCI::QueueCommand(xhci_trb *trb) i = fCmdIdx; j = fCmdCcs; - TRACE("command[%u] = %lx (0x%016llx, 0x%08lx, 0x%08lx)\n", - i, TRB_3_TYPE_GET(trb->dwtrb3), + TRACE("command[%u] = %" B_PRIx32 " (0x%016" B_PRIx64 ", 0x%08" B_PRIx32 + ", 0x%08" B_PRIx32 ")\n", i, TRB_3_TYPE_GET(trb->dwtrb3), trb->qwtrb0, trb->dwtrb2, trb->dwtrb3); fCmdRing[i].qwtrb0 = trb->qwtrb0; @@ -1722,7 +1735,8 @@ XHCI::HandleTransferComplete(xhci_trb *trb) xhci_endpoint *endpoint = &device->endpoints[endpointNumber - 1]; for (xhci_td *td = endpoint->td_head; td != NULL; td = td->next) { int64 offset = source - td->this_phy; - TRACE("HandleTransferComplete td %p offset %lld\n", td, offset); + TRACE("HandleTransferComplete td %p offset %" B_PRId64 "\n", td, + offset); _UnlinkDescriptorForPipe(td, endpoint); // add descriptor to finished list (to be processed and freed) @@ -1759,14 +1773,15 @@ XHCI::DoCommand(xhci_trb *trb) TRACE("Command Complete\n"); if (TRB_2_COMP_CODE_GET(fCmdResult[0]) != COMP_SUCCESS) { uint32 errorCode = TRB_2_COMP_CODE_GET(fCmdResult[0]); - TRACE_ERROR("unsuccessful command %s (%ld)\n", + TRACE_ERROR("unsuccessful command %s (%" B_PRId32 ")\n", xhci_error_string(errorCode), errorCode); status = B_IO_ERROR; } trb->dwtrb2 = fCmdResult[0]; trb->dwtrb3 = fCmdResult[1]; - TRACE("Storing trb 0x%08lx 0x%08lx\n", trb->dwtrb2, trb->dwtrb3); + TRACE("Storing trb 0x%08" B_PRIx32 " 0x%08" B_PRIx32 "\n", trb->dwtrb2, + trb->dwtrb3); Unlock(); return status; @@ -1944,8 +1959,9 @@ XHCI::CompleteEvents() uint8 event = TRB_3_TYPE_GET(temp); - TRACE("event[%u] = %u (0x%016llx 0x%08lx 0x%08lx)\n", i, event, - fEventRing[i].qwtrb0, fEventRing[i].dwtrb2, fEventRing[i].dwtrb3); + TRACE("event[%u] = %u (0x%016" B_PRIx64 " 0x%08" B_PRIx32 " 0x%08" + B_PRIx32 ")\n", i, event, fEventRing[i].qwtrb0, + fEventRing[i].dwtrb2, fEventRing[i].dwtrb3); switch (event) { case TRB_TYPE_COMMAND_COMPLETION: HandleCmdComplete(&fEventRing[i]); diff --git a/src/add-ons/kernel/busses/usb/xhci.h b/src/add-ons/kernel/busses/usb/xhci.h index 0983aa84b2..8c35c34955 100644 --- a/src/add-ons/kernel/busses/usb/xhci.h +++ b/src/add-ons/kernel/busses/usb/xhci.h @@ -35,8 +35,8 @@ enum xhci_state { typedef struct xhci_td { struct xhci_trb trbs[XHCI_MAX_TRBS_PER_TD]; - addr_t this_phy; // A physical pointer to this address - addr_t buffer_phy[XHCI_MAX_TRBS_PER_TD]; + phys_addr_t this_phy; // A physical pointer to this address + phys_addr_t buffer_phy[XHCI_MAX_TRBS_PER_TD]; void *buffer_log[XHCI_MAX_TRBS_PER_TD]; // Pointer to the logical buffer size_t buffer_size[XHCI_MAX_TRBS_PER_TD]; // Size of the buffer uint8 buffer_count; @@ -51,7 +51,7 @@ typedef struct xhci_endpoint { xhci_device *device; xhci_td *td_head; struct xhci_trb *trbs; // [XHCI_MAX_TRANSFERS] - addr_t trb_addr; + phys_addr_t trb_addr; uint8 used; uint8 current; mutex lock; @@ -63,15 +63,15 @@ typedef struct xhci_device { uint8 address; enum xhci_state state; area_id trb_area; - addr_t trb_addr; + phys_addr_t trb_addr; struct xhci_trb (*trbs); // [XHCI_MAX_ENDPOINTS - 1][XHCI_MAX_TRANSFERS] area_id input_ctx_area; - addr_t input_ctx_addr; + phys_addr_t input_ctx_addr; struct xhci_input_device_ctx *input_ctx; area_id device_ctx_area; - addr_t device_ctx_addr; + phys_addr_t device_ctx_addr; struct xhci_device_ctx *device_ctx; xhci_endpoint endpoints[XHCI_MAX_ENDPOINTS - 1]; diff --git a/src/add-ons/kernel/busses/virtio/Jamfile b/src/add-ons/kernel/busses/virtio/Jamfile new file mode 100644 index 0000000000..934cd688bb --- /dev/null +++ b/src/add-ons/kernel/busses/virtio/Jamfile @@ -0,0 +1,16 @@ +SubDir HAIKU_TOP src add-ons kernel busses virtio ; + +SubDirC++Flags -fno-rtti ; + +UsePrivateHeaders kernel virtio ; + +KernelAddon virtio_pci : + virtio_pci.cpp + + kernel_cpp.cpp + ; + +SEARCH on [ FGristFiles + kernel_cpp.cpp + ] = [ FDirName $(HAIKU_TOP) src system kernel util ] ; + diff --git a/src/add-ons/kernel/busses/virtio/virtio_pci.cpp b/src/add-ons/kernel/busses/virtio/virtio_pci.cpp new file mode 100644 index 0000000000..8d2ff0acbd --- /dev/null +++ b/src/add-ons/kernel/busses/virtio/virtio_pci.cpp @@ -0,0 +1,480 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include + +#include +#include + +#include "virtio_pci.h" + + +//#define TRACE_VIRTIO +#ifdef TRACE_VIRTIO +# define TRACE(x...) dprintf("\33[33mvirtio_pci:\33[0m " x) +#else +# define TRACE(x...) ; +#endif +#define ERROR(x...) dprintf("\33[33mvirtio_pci:\33[0m " x) +#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) + + +#define VIRTIO_PCI_DEVICE_MODULE_NAME "busses/virtio/virtio_pci/driver_v1" +#define VIRTIO_PCI_SIM_MODULE_NAME "busses/virtio/virtio_pci/device/v1" + +#define VIRTIO_PCI_CONTROLLER_TYPE_NAME "virtio pci controller" + + +typedef struct { + pci_device_module_info* pci; + pci_device* device; + uint16 config_base; + addr_t base_addr; + uint8 irq; + virtio_sim sim; + + device_node* node; +} virtio_pci_sim_info; + + +device_manager_info* gDeviceManager; +virtio_for_controller_interface* gVirtio; + + +int32 +virtio_pci_interrupt(void *data) +{ + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)data; + uint8 isr = bus->pci->read_io_8(bus->device, + bus->base_addr + VIRTIO_PCI_ISR); + if (isr == 0) + return B_UNHANDLED_INTERRUPT; + + if (isr & VIRTIO_PCI_ISR_CONFIG) + gVirtio->config_interrupt_handler(bus->sim); + + if (isr & VIRTIO_PCI_ISR_INTR) + gVirtio->queue_interrupt_handler(bus->sim, INT16_MAX); + + return B_HANDLED_INTERRUPT; +} + + +static void +set_sim(void* cookie, virtio_sim sim) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + bus->sim = sim; +} + + +static status_t +read_host_features(void* cookie, uint32 *features) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + + TRACE("read_host_features() %p node %p pci %p device %p\n", bus, + bus->node, bus->pci, bus->device); + + *features = bus->pci->read_io_32(bus->device, + bus->base_addr + VIRTIO_PCI_HOST_FEATURES); + return B_OK; +} + + +static status_t +write_guest_features(void* cookie, uint32 features) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + bus->pci->write_io_32(bus->device, bus->base_addr + + VIRTIO_PCI_GUEST_FEATURES, features); + return B_OK; +} + + +uint8 +get_status(void* cookie) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + return bus->pci->read_io_8(bus->device, bus->base_addr + + VIRTIO_PCI_STATUS); +} + + +void +set_status(void* cookie, uint8 status) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + bus->pci->write_io_8(bus->device, bus->base_addr + VIRTIO_PCI_STATUS, + status); +} + + +status_t +read_device_config(void* cookie, uint8 _offset, void* _buffer, + size_t bufferSize) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + + addr_t offset = bus->base_addr + bus->config_base + _offset; + uint8* buffer = (uint8*)_buffer; + while (bufferSize > 0) { + uint8 size = 4; + if (bufferSize == 1) { + size = 1; + *buffer = bus->pci->read_io_8(bus->device, + offset); + } else if (bufferSize <= 3) { + size = 2; + *(uint16*)buffer = bus->pci->read_io_16(bus->device, + offset); + } else { + *(uint32*)buffer = bus->pci->read_io_32(bus->device, + offset); + } + buffer += size; + bufferSize -= size; + offset += size; + } + + return B_OK; +} + + +status_t +write_device_config(void* cookie, uint8 _offset, const void* _buffer, + size_t bufferSize) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + + addr_t offset = bus->base_addr + bus->config_base + _offset; + const uint8* buffer = (const uint8*)_buffer; + while (bufferSize > 0) { + uint8 size = 4; + if (bufferSize == 1) { + size = 1; + bus->pci->write_pci_config(bus->device, + offset, size, *buffer); + } else if (bufferSize <= 3) { + size = 2; + bus->pci->write_pci_config(bus->device, + offset, size, *(const uint16*)buffer); + } else { + bus->pci->write_pci_config(bus->device, + offset, size, *(const uint32*)buffer); + } + buffer += size; + bufferSize -= size; + offset += size; + } + return B_OK; +} + + +uint16 +get_queue_ring_size(void* cookie, uint16 queue) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + bus->pci->write_io_16(bus->device, bus->base_addr + VIRTIO_PCI_QUEUE_SEL, + queue); + return bus->pci->read_io_16(bus->device, bus->base_addr + + VIRTIO_PCI_QUEUE_NUM); +} + + +status_t +setup_queue(void* cookie, uint16 queue, phys_addr_t phy) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + bus->pci->write_io_16(bus->device, bus->base_addr + VIRTIO_PCI_QUEUE_SEL, + queue); + bus->pci->write_io_32(bus->device, bus->base_addr + VIRTIO_PCI_QUEUE_PFN, + (uint32)phy >> VIRTIO_PCI_QUEUE_ADDR_SHIFT); + return B_OK; +} + + +status_t +setup_interrupt(void* cookie) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + + // setup interrupt handler + status_t status = install_io_interrupt_handler(bus->irq, + virtio_pci_interrupt, bus, 0); + if (status != B_OK) { + ERROR("can't install interrupt handler\n"); + return status; + } + + return B_OK; +} + + +void +notify_queue(void* cookie, uint16 queue) +{ + CALLED(); + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)cookie; + bus->pci->write_io_16(bus->device, bus->base_addr + + VIRTIO_PCI_QUEUE_NOTIFY, queue); +} + + +// #pragma mark - + + +static status_t +init_bus(device_node* node, void** bus_cookie) +{ + CALLED(); + status_t status = B_OK; + + virtio_pci_sim_info* bus = new(std::nothrow) virtio_pci_sim_info; + if (bus == NULL) { + return B_NO_MEMORY; + } + + pci_device_module_info* pci; + pci_device* device; + { + device_node* parent = gDeviceManager->get_parent_node(node); + device_node* pciParent = gDeviceManager->get_parent_node(parent); + gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci, + (void**)&device); + gDeviceManager->put_node(pciParent); + gDeviceManager->put_node(parent); + } + + bus->node = node; + bus->pci = pci; + bus->device = device; + // TODO MSI implies 24 + bus->config_base = 20; + + pci_info pciInfo; + pci->get_pci_info(device, &pciInfo); + + // legacy interrupt + bus->base_addr = pciInfo.u.h0.base_registers[0]; + bus->irq = pciInfo.u.h0.interrupt_line; + if (bus->irq == 0 || bus->irq == 0xff) { + ERROR("PCI IRQ not assigned\n"); + delete bus; + return B_ERROR; + } + + // enable bus master and io + uint16 pcicmd = pci->read_pci_config(device, PCI_command, 2); + pcicmd &= ~(PCI_command_memory | PCI_command_int_disable); + pcicmd |= PCI_command_master | PCI_command_io; + pci->write_pci_config(device, PCI_command, 2, pcicmd); + + set_status(bus, VIRTIO_CONFIG_STATUS_RESET); + set_status(bus, VIRTIO_CONFIG_STATUS_ACK); + + TRACE("init_bus() %p node %p pci %p device %p\n", bus, node, + bus->pci, bus->device); + + *bus_cookie = bus; + return B_OK; +} + + +static void +uninit_bus(void* bus_cookie) +{ + virtio_pci_sim_info* bus = (virtio_pci_sim_info*)bus_cookie; + delete bus; +} + + +static void +bus_removed(void* bus_cookie) +{ + return; +} + + +// #pragma mark - + + +static status_t +register_child_devices(void* cookie) +{ + CALLED(); + device_node* node = (device_node*)cookie; + device_node* parent = gDeviceManager->get_parent_node(node); + pci_device_module_info* pci; + pci_device* device; + gDeviceManager->get_driver(parent, (driver_module_info**)&pci, + (void**)&device); + + uint16 pciSubDeviceId = pci->read_pci_config(device, PCI_subsystem_id, + 2); + + char prettyName[25]; + sprintf(prettyName, "Virtio Device %" B_PRIu16, pciSubDeviceId); + + device_attr attrs[] = { + // properties of this controller for virtio bus manager + { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, + { string: prettyName }}, + { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, + { string: VIRTIO_FOR_CONTROLLER_MODULE_NAME }}, + + // private data to identify the device + { VIRTIO_DEVICE_TYPE_ITEM, B_UINT16_TYPE, + { ui16: pciSubDeviceId }}, + { VIRTIO_VRING_ALIGNMENT_ITEM, B_UINT16_TYPE, + { ui16: VIRTIO_PCI_VRING_ALIGN }}, + { NULL } + }; + + return gDeviceManager->register_node(node, VIRTIO_PCI_SIM_MODULE_NAME, + attrs, NULL, &node); +} + + +static status_t +init_device(device_node* node, void** device_cookie) +{ + CALLED(); + *device_cookie = node; + return B_OK; +} + + +static status_t +register_device(device_node* parent) +{ + device_attr attrs[] = { + {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Virtio PCI"}}, + {} + }; + + return gDeviceManager->register_node(parent, VIRTIO_PCI_DEVICE_MODULE_NAME, + attrs, NULL, NULL); +} + + +static float +supports_device(device_node* parent) +{ + CALLED(); + const char* bus; + uint16 vendorID, deviceID; + + // make sure parent is a PCI Virtio device node + if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) != B_OK + || gDeviceManager->get_attr_uint16(parent, B_DEVICE_VENDOR_ID, + &vendorID, false) < B_OK + || gDeviceManager->get_attr_uint16(parent, B_DEVICE_ID, &deviceID, + false) < B_OK) + return -1; + + if (strcmp(bus, "pci") != 0) + return 0.0f; + + if (vendorID == VIRTIO_PCI_VENDORID) { + if (deviceID < VIRTIO_PCI_DEVICEID_MIN + && deviceID > VIRTIO_PCI_DEVICEID_MAX) { + return 0.0f; + } + + pci_device_module_info* pci; + pci_device* device; + gDeviceManager->get_driver(parent, (driver_module_info**)&pci, + (void**)&device); + uint8 pciSubDeviceId = pci->read_pci_config(device, PCI_revision, + 1); + if (pciSubDeviceId != VIRTIO_PCI_ABI_VERSION) + return 0.0f; + + TRACE("Virtio device found! vendor 0x%04x, device 0x%04x\n", vendorID, + deviceID); + return 0.8f; + } + + return 0.0f; +} + + +// #pragma mark - + + +module_dependency module_dependencies[] = { + { VIRTIO_FOR_CONTROLLER_MODULE_NAME, (module_info**)&gVirtio }, + { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager }, + {} +}; + + +static virtio_sim_interface gVirtioPCIDeviceModule = { + { + { + VIRTIO_PCI_SIM_MODULE_NAME, + 0, + NULL + }, + + NULL, // supports device + NULL, // register device + init_bus, + uninit_bus, + NULL, // register child devices + NULL, // rescan + bus_removed, + }, + + set_sim, + read_host_features, + write_guest_features, + get_status, + set_status, + read_device_config, + write_device_config, + get_queue_ring_size, + setup_queue, + setup_interrupt, + notify_queue +}; + + +static driver_module_info sVirtioDevice = { + { + VIRTIO_PCI_DEVICE_MODULE_NAME, + 0, + NULL + }, + + supports_device, + register_device, + init_device, + NULL, // uninit + register_child_devices, + NULL, // rescan + NULL, // device removed +}; + +module_info* modules[] = { + (module_info* )&sVirtioDevice, + (module_info* )&gVirtioPCIDeviceModule, + NULL +}; + diff --git a/src/add-ons/kernel/busses/virtio/virtio_pci.h b/src/add-ons/kernel/busses/virtio/virtio_pci.h new file mode 100644 index 0000000000..485cf4ff5b --- /dev/null +++ b/src/add-ons/kernel/busses/virtio/virtio_pci.h @@ -0,0 +1,87 @@ +/*- + * Copyright IBM Corp. 2007 + * + * Authors: + * Anthony Liguori + * + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * 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. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM 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. + * + * $FreeBSD$ + */ + +#ifndef _VIRTIO_PCI_H +#define _VIRTIO_PCI_H + +/* VirtIO PCI vendor/device ID. */ +#define VIRTIO_PCI_VENDORID 0x1AF4 +#define VIRTIO_PCI_DEVICEID_MIN 0x1000 +#define VIRTIO_PCI_DEVICEID_MAX 0x103F + +/* VirtIO ABI version, this must match exactly. */ +#define VIRTIO_PCI_ABI_VERSION 0 + +/* + * VirtIO Header, located in BAR 0. + */ +#define VIRTIO_PCI_HOST_FEATURES 0 /* host's supported features (32bit, RO)*/ +#define VIRTIO_PCI_GUEST_FEATURES 4 /* guest's supported features (32, RW) */ +#define VIRTIO_PCI_QUEUE_PFN 8 /* physical address of VQ (32, RW) */ +#define VIRTIO_PCI_QUEUE_NUM 12 /* number of ring entries (16, RO) */ +#define VIRTIO_PCI_QUEUE_SEL 14 /* current VQ selection (16, RW) */ +#define VIRTIO_PCI_QUEUE_NOTIFY 16 /* notify host regarding VQ (16, RW) */ +#define VIRTIO_PCI_STATUS 18 /* device status register (8, RW) */ +#define VIRTIO_PCI_ISR 19 /* interrupt status register, reading + * also clears the register (8, RO) */ +/* Only if MSIX is enabled: */ +#define VIRTIO_MSI_CONFIG_VECTOR 20 /* configuration change vector (16, RW) */ +#define VIRTIO_MSI_QUEUE_VECTOR 22 /* vector for selected VQ notifications + (16, RW) */ + +/* The bit of the ISR which indicates a device has an interrupt. */ +#define VIRTIO_PCI_ISR_INTR 0x1 +/* The bit of the ISR which indicates a device configuration change. */ +#define VIRTIO_PCI_ISR_CONFIG 0x2 +/* Vector value used to disable MSI for queue. */ +#define VIRTIO_MSI_NO_VECTOR 0xFFFF + +/* + * The remaining space is defined by each driver as the per-driver + * configuration space. + */ +#define VIRTIO_PCI_CONFIG(sc) \ + (((sc)->vtpci_flags & VTPCI_FLAG_MSIX) ? 24 : 20) + +/* + * How many bits to shift physical queue address written to QUEUE_PFN. + * 12 is historical, and due to x86 page size. + */ +#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 + +/* The alignment to use between consumer and producer parts of vring. */ +#define VIRTIO_PCI_VRING_ALIGN 4096 + +#endif /* _VIRTIO_PCI_H */ diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp index 18ebc55906..a50a149b8a 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp @@ -107,9 +107,10 @@ get_geometry(das_handle* handle, device_geometry* geometry) geometry->read_only = false; geometry->write_once = false; - TRACE("scsi_disk: get_geometry(): %ld, %ld, %ld, %ld, %d, %d, %d, %d\n", - geometry->bytes_per_sector, geometry->sectors_per_track, - geometry->cylinder_count, geometry->head_count, geometry->device_type, + TRACE("scsi_disk: get_geometry(): %" B_PRId32 ", %" B_PRId32 ", %" B_PRId32 + ", %" B_PRId32 ", %d, %d, %d, %d\n", geometry->bytes_per_sector, + geometry->sectors_per_track, geometry->cylinder_count, + geometry->head_count, geometry->device_type, geometry->removable, geometry->read_only, geometry->write_once); return B_OK; @@ -209,7 +210,6 @@ das_uninit_device(void* _cookie) das_driver_info* info = (das_driver_info*)_cookie; delete info->io_scheduler; - delete info->dma_resource; } @@ -324,7 +324,7 @@ das_ioctl(void* cookie, uint32 op, void* buffer, size_t length) das_handle* handle = (das_handle*)cookie; das_driver_info* info = handle->info; - TRACE("ioctl(op = %ld)\n", op); + TRACE("ioctl(op = %" B_PRIu32 ")\n", op); switch (op) { case B_GET_DEVICE_SIZE: @@ -398,8 +398,8 @@ das_ioctl(void* cookie, uint32 op, void* buffer, size_t length) static void das_set_capacity(das_driver_info* info, uint64 capacity, uint32 blockSize) { - TRACE("das_set_capacity(device = %p, capacity = %Ld, blockSize = %ld)\n", - info, capacity, blockSize); + TRACE("das_set_capacity(device = %p, capacity = %" B_PRIu64 + ", blockSize = %" B_PRIu32 ")\n", info, capacity, blockSize); // get log2, if possible uint32 blockShift = log2(blockSize); @@ -555,6 +555,7 @@ das_init_driver(device_node *node, void **cookie) &callbacks, info->scsi_device, info->scsi, info->node, info->removable, 10, &info->scsi_periph_device); if (status != B_OK) { + delete info->dma_resource; free(info); return status; } @@ -570,6 +571,7 @@ das_uninit_driver(void *_cookie) das_driver_info* info = (das_driver_info*)_cookie; sSCSIPeripheral->unregister_device(info->scsi_periph_device); + delete info->dma_resource; free(info); } diff --git a/src/add-ons/kernel/drivers/disk/virtual/Jamfile b/src/add-ons/kernel/drivers/disk/virtual/Jamfile index 7952c77f19..6165da530d 100644 --- a/src/add-ons/kernel/drivers/disk/virtual/Jamfile +++ b/src/add-ons/kernel/drivers/disk/virtual/Jamfile @@ -3,3 +3,4 @@ SubDir HAIKU_TOP src add-ons kernel drivers disk virtual ; #SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual fmap ; SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual nbd ; SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual remote_disk ; +SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual virtio_block ; diff --git a/src/add-ons/kernel/drivers/disk/virtual/virtio_block/Jamfile b/src/add-ons/kernel/drivers/disk/virtual/virtio_block/Jamfile new file mode 100644 index 0000000000..9bfba08da9 --- /dev/null +++ b/src/add-ons/kernel/drivers/disk/virtual/virtio_block/Jamfile @@ -0,0 +1,9 @@ +SubDir HAIKU_TOP src add-ons kernel drivers disk virtual virtio_block ; + +UsePrivateKernelHeaders ; +UsePrivateHeaders drivers virtio ; +SubDirHdrs $(HAIKU_TOP) src system kernel device_manager ; + +KernelAddon virtio_block : + virtio_block.cpp +; diff --git a/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_blk.h b/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_blk.h new file mode 100644 index 0000000000..35acaea8d2 --- /dev/null +++ b/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_blk.h @@ -0,0 +1,117 @@ +/*- + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * 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. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM 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. + * + * $FreeBSD$ + */ + +#ifndef _VIRTIO_BLK_H +#define _VIRTIO_BLK_H + +/* Feature bits */ +#define VIRTIO_BLK_F_BARRIER 0x0001 /* Does host support barriers? */ +#define VIRTIO_BLK_F_SIZE_MAX 0x0002 /* Indicates maximum segment size */ +#define VIRTIO_BLK_F_SEG_MAX 0x0004 /* Indicates maximum # of segments */ +#define VIRTIO_BLK_F_GEOMETRY 0x0010 /* Legacy geometry available */ +#define VIRTIO_BLK_F_RO 0x0020 /* Disk is read-only */ +#define VIRTIO_BLK_F_BLK_SIZE 0x0040 /* Block size of disk is available*/ +#define VIRTIO_BLK_F_SCSI 0x0080 /* Supports scsi command passthru */ +#define VIRTIO_BLK_F_FLUSH 0x0200 /* Cache flush command support */ +#define VIRTIO_BLK_F_TOPOLOGY 0x0400 /* Topology information is available */ + +#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */ + +struct virtio_blk_config { + /* The capacity (in 512-byte sectors). */ + uint64_t capacity; + /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */ + uint32_t size_max; + /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ + uint32_t seg_max; + /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ + struct virtio_blk_geometry { + uint16_t cylinders; + uint8_t heads; + uint8_t sectors; + } geometry; + + /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ + uint32_t blk_size; +} _PACKED; + +/* + * Command types + * + * Usage is a bit tricky as some bits are used as flags and some are not. + * + * Rules: + * VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or + * VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own + * and may not be combined with any of the other flags. + */ + +/* These two define direction. */ +#define VIRTIO_BLK_T_IN 0 +#define VIRTIO_BLK_T_OUT 1 + +/* This bit says it's a scsi command, not an actual read or write. */ +#define VIRTIO_BLK_T_SCSI_CMD 2 + +/* Cache flush command */ +#define VIRTIO_BLK_T_FLUSH 4 + +/* Get device ID command */ +#define VIRTIO_BLK_T_GET_ID 8 + +/* Barrier before this op. */ +#define VIRTIO_BLK_T_BARRIER 0x80000000 + +/* ID string length */ +#define VIRTIO_BLK_ID_BYTES 20 + +/* This is the first element of the read scatter-gather list. */ +struct virtio_blk_outhdr { + /* VIRTIO_BLK_T* */ + uint32_t type; + /* io priority. */ + uint32_t ioprio; + /* Sector (ie. 512 byte offset) */ + uint64_t sector; +}; + +struct virtio_scsi_inhdr { + uint32_t errors; + uint32_t data_len; + uint32_t sense_len; + uint32_t residual; +}; + +/* And this is the final byte of the write scatter-gather list. */ +#define VIRTIO_BLK_S_OK 0 +#define VIRTIO_BLK_S_IOERR 1 +#define VIRTIO_BLK_S_UNSUPP 2 + +#endif /* _VIRTIO_BLK_H */ diff --git a/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_block.cpp b/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_block.cpp new file mode 100644 index 0000000000..9198214b47 --- /dev/null +++ b/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_block.cpp @@ -0,0 +1,662 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include "virtio_blk.h" + + +struct DMAResource; +struct IOScheduler; + + +static const uint8 kDriveIcon[] = { + 0x6e, 0x63, 0x69, 0x66, 0x08, 0x03, 0x01, 0x00, 0x00, 0x02, 0x00, 0x16, + 0x02, 0x3c, 0xc7, 0xee, 0x38, 0x9b, 0xc0, 0xba, 0x16, 0x57, 0x3e, 0x39, + 0xb0, 0x49, 0x77, 0xc8, 0x42, 0xad, 0xc7, 0x00, 0xff, 0xff, 0xd3, 0x02, + 0x00, 0x06, 0x02, 0x3c, 0x96, 0x32, 0x3a, 0x4d, 0x3f, 0xba, 0xfc, 0x01, + 0x3d, 0x5a, 0x97, 0x4b, 0x57, 0xa5, 0x49, 0x84, 0x4d, 0x00, 0x47, 0x47, + 0x47, 0xff, 0xa5, 0xa0, 0xa0, 0x02, 0x00, 0x16, 0x02, 0xbc, 0x59, 0x2f, + 0xbb, 0x29, 0xa7, 0x3c, 0x0c, 0xe4, 0xbd, 0x0b, 0x7c, 0x48, 0x92, 0xc0, + 0x4b, 0x79, 0x66, 0x00, 0x7d, 0xff, 0xd4, 0x02, 0x00, 0x06, 0x02, 0x38, + 0xdb, 0xb4, 0x39, 0x97, 0x33, 0xbc, 0x4a, 0x33, 0x3b, 0xa5, 0x42, 0x48, + 0x6e, 0x66, 0x49, 0xee, 0x7b, 0x00, 0x59, 0x67, 0x56, 0xff, 0xeb, 0xb2, + 0xb2, 0x03, 0xa7, 0xff, 0x00, 0x03, 0xff, 0x00, 0x00, 0x04, 0x01, 0x80, + 0x07, 0x0a, 0x06, 0x22, 0x3c, 0x22, 0x49, 0x44, 0x5b, 0x5a, 0x3e, 0x5a, + 0x31, 0x39, 0x25, 0x0a, 0x04, 0x22, 0x3c, 0x44, 0x4b, 0x5a, 0x31, 0x39, + 0x25, 0x0a, 0x04, 0x44, 0x4b, 0x44, 0x5b, 0x5a, 0x3e, 0x5a, 0x31, 0x0a, + 0x04, 0x22, 0x3c, 0x22, 0x49, 0x44, 0x5b, 0x44, 0x4b, 0x08, 0x02, 0x27, + 0x43, 0xb8, 0x14, 0xc1, 0xf1, 0x08, 0x02, 0x26, 0x43, 0x29, 0x44, 0x0a, + 0x05, 0x44, 0x5d, 0x49, 0x5d, 0x60, 0x3e, 0x5a, 0x3b, 0x5b, 0x3f, 0x08, + 0x0a, 0x07, 0x01, 0x06, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x01, 0x17, + 0x84, 0x00, 0x04, 0x0a, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x02, 0x01, 0x02, + 0x00, 0x0a, 0x03, 0x01, 0x03, 0x00, 0x0a, 0x04, 0x01, 0x04, 0x10, 0x01, + 0x17, 0x85, 0x20, 0x04, 0x0a, 0x06, 0x01, 0x05, 0x30, 0x24, 0xb3, 0x99, + 0x01, 0x17, 0x82, 0x00, 0x04, 0x0a, 0x05, 0x01, 0x05, 0x30, 0x20, 0xb2, + 0xe6, 0x01, 0x17, 0x82, 0x00, 0x04 +}; + + +#define VIRTIO_BLOCK_DRIVER_MODULE_NAME "drivers/disk/virtual/virtio_block/driver_v1" +#define VIRTIO_BLOCK_DEVICE_MODULE_NAME "drivers/disk/virtual/virtio_block/device_v1" +#define VIRTIO_BLOCK_DEVICE_ID_GENERATOR "virtio_block/device_id" + + +typedef struct { + device_node* node; + ::virtio_device virtio_device; + virtio_device_interface* virtio; + ::virtio_queue virtio_queue; + IOScheduler* io_scheduler; + DMAResource* dma_resource; + + struct virtio_blk_config config; + + uint32 features; + uint64 capacity; + uint32 block_size; + + sem_id sem_cb; +} virtio_block_driver_info; + + +typedef struct { + virtio_block_driver_info* info; +} virtio_block_handle; + + +#include +#include +#include + +#include + +#include "dma_resources.h" +#include "IORequest.h" +#include "IOSchedulerSimple.h" + + +//#define TRACE_VIRTIO_BLOCK +#ifdef TRACE_VIRTIO_BLOCK +# define TRACE(x...) dprintf("virtio_block: " x) +#else +# define TRACE(x...) ; +#endif +#define ERROR(x...) dprintf("\33[33mvirtio_block:\33[0m " x) +#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) + + +static device_manager_info* sDeviceManager; + + +void virtio_block_set_capacity(virtio_block_driver_info* info, uint64 capacity, + uint32 blockSize); + + +const char * +get_feature_name(uint32 feature) +{ + switch (feature) { + case VIRTIO_BLK_F_BARRIER: + return "host barrier"; + case VIRTIO_BLK_F_SIZE_MAX: + return "maximum segment size"; + case VIRTIO_BLK_F_SEG_MAX: + return "maximum segment count"; + case VIRTIO_BLK_F_GEOMETRY: + return "disk geometry"; + case VIRTIO_BLK_F_RO: + return "read only"; + case VIRTIO_BLK_F_BLK_SIZE: + return "block size"; + case VIRTIO_BLK_F_SCSI: + return "scsi commands"; + case VIRTIO_BLK_F_FLUSH: + return "flush command"; + case VIRTIO_BLK_F_TOPOLOGY: + return "topology"; + } + return NULL; +} + + +static status_t +get_geometry(virtio_block_handle* handle, device_geometry* geometry) +{ + virtio_block_driver_info* info = handle->info; + + devfs_compute_geometry_size(geometry, info->capacity, info->block_size); + + geometry->device_type = B_DISK; + geometry->removable = false; + + geometry->read_only = ((info->features & VIRTIO_BLK_F_RO) != 0); + geometry->write_once = false; + + TRACE("virtio_block: get_geometry(): %ld, %ld, %ld, %ld, %d, %d, %d, %d\n", + geometry->bytes_per_sector, geometry->sectors_per_track, + geometry->cylinder_count, geometry->head_count, geometry->device_type, + geometry->removable, geometry->read_only, geometry->write_once); + + return B_OK; +} + + +static int +log2(uint32 x) +{ + int y; + + for (y = 31; y >= 0; --y) { + if (x == ((uint32)1 << y)) + break; + } + + return y; +} + + +static void +virtio_block_callback(void* cookie) +{ + virtio_block_driver_info* info = (virtio_block_driver_info*)cookie; + + release_sem(info->sem_cb); +} + + +static status_t +do_io(void* cookie, IOOperation* operation) +{ + virtio_block_driver_info* info = (virtio_block_driver_info*)cookie; + + size_t bytesTransferred = 0; + status_t status = B_OK; + + physical_entry entries[operation->VecCount() + 2]; + + void *buffer = malloc(sizeof(struct virtio_blk_outhdr) + sizeof(uint8)); + struct virtio_blk_outhdr *header = (struct virtio_blk_outhdr*)buffer; + header->type = operation->IsWrite() ? VIRTIO_BLK_T_OUT : VIRTIO_BLK_T_IN; + header->sector = operation->Offset() / 512; + header->ioprio = 1; + + uint8* ack = (uint8*)buffer + sizeof(struct virtio_blk_outhdr); + *ack = 0xff; + + get_memory_map(buffer, sizeof(struct virtio_blk_outhdr) + sizeof(uint8), + &entries[0], 1); + entries[operation->VecCount() + 1].address = entries[0].address + + sizeof(struct virtio_blk_outhdr); + entries[operation->VecCount() + 1].size = sizeof(uint8); + entries[0].size = sizeof(struct virtio_blk_outhdr); + + memcpy(entries + 1, operation->Vecs(), operation->VecCount() + * sizeof(physical_entry)); + + info->virtio->queue_request_v(info->virtio_queue, entries, + 1 + (operation->IsWrite() ? operation->VecCount() : 0 ), + 1 + (operation->IsWrite() ? 0 : operation->VecCount()), + virtio_block_callback, info); + + acquire_sem(info->sem_cb); + + switch (*ack) { + case VIRTIO_BLK_S_OK: + status = B_OK; + bytesTransferred = operation->Length(); + break; + case VIRTIO_BLK_S_UNSUPP: + status = ENOTSUP; + break; + default: + status = EIO; + break; + } + free(buffer); + + info->io_scheduler->OperationCompleted(operation, status, + bytesTransferred); + return status; +} + + +// #pragma mark - device module API + + +static status_t +virtio_block_init_device(void* _info, void** _cookie) +{ + CALLED(); + virtio_block_driver_info* info = (virtio_block_driver_info*)_info; + + device_node* parent = sDeviceManager->get_parent_node(info->node); + sDeviceManager->get_driver(parent, (driver_module_info **)&info->virtio, + (void **)&info->virtio_device); + sDeviceManager->put_node(parent); + + info->virtio->negociate_features(info->virtio_device, + VIRTIO_BLK_F_BARRIER | VIRTIO_BLK_F_SIZE_MAX + | VIRTIO_BLK_F_SEG_MAX | VIRTIO_BLK_F_GEOMETRY + | VIRTIO_BLK_F_RO | VIRTIO_BLK_F_BLK_SIZE + | VIRTIO_BLK_F_FLUSH | VIRTIO_FEATURE_RING_INDIRECT_DESC, + &info->features, &get_feature_name); + + status_t status = info->virtio->read_device_config( + info->virtio_device, 0, &info->config, + sizeof(struct virtio_blk_config)); + if (status != B_OK) + return status; + + // and get (initial) capacity + uint32 block_size = 512; + if ((info->features & VIRTIO_BLK_F_BLK_SIZE) != 0) + block_size = info->config.blk_size; + uint64 capacity = info->config.capacity * 512 / block_size; + + virtio_block_set_capacity(info, capacity, block_size); + + TRACE("virtio_block: capacity: %" B_PRIu64 ", block_size %" B_PRIu32 "\n", + info->capacity, info->block_size); + + status = info->virtio->alloc_queues(info->virtio_device, 1, + &info->virtio_queue); + if (status != B_OK) { + ERROR("queue allocation failed (%s)\n", strerror(status)); + return status; + } + status = info->virtio->setup_interrupt(info->virtio_device, NULL, NULL); + + *_cookie = info; + return status; +} + + +static void +virtio_block_uninit_device(void* _cookie) +{ + CALLED(); + virtio_block_driver_info* info = (virtio_block_driver_info*)_cookie; + + delete info->io_scheduler; + delete info->dma_resource; +} + + +static status_t +virtio_block_open(void* _info, const char* path, int openMode, void** _cookie) +{ + CALLED(); + virtio_block_driver_info* info = (virtio_block_driver_info*)_info; + + virtio_block_handle* handle = (virtio_block_handle*)malloc( + sizeof(virtio_block_handle)); + if (handle == NULL) + return B_NO_MEMORY; + + handle->info = info; + + *_cookie = handle; + return B_OK; +} + + +static status_t +virtio_block_close(void* cookie) +{ + //virtio_block_handle* handle = (virtio_block_handle*)cookie; + CALLED(); + + return B_OK; +} + + +static status_t +virtio_block_free(void* cookie) +{ + CALLED(); + virtio_block_handle* handle = (virtio_block_handle*)cookie; + + free(handle); + return B_OK; +} + + +static status_t +virtio_block_read(void* cookie, off_t pos, void* buffer, size_t* _length) +{ + CALLED(); + virtio_block_handle* handle = (virtio_block_handle*)cookie; + size_t length = *_length; + + IORequest request; + status_t status = request.Init(pos, (addr_t)buffer, length, false, 0); + if (status != B_OK) + return status; + + status = handle->info->io_scheduler->ScheduleRequest(&request); + if (status != B_OK) + return status; + + status = request.Wait(0, 0); + if (status == B_OK) + *_length = length; + else + dprintf("read(): request.Wait() returned: %s\n", strerror(status)); + + return status; +} + + +static status_t +virtio_block_write(void* cookie, off_t pos, const void* buffer, + size_t* _length) +{ + CALLED(); + virtio_block_handle* handle = (virtio_block_handle*)cookie; + size_t length = *_length; + + IORequest request; + status_t status = request.Init(pos, (addr_t)buffer, length, true, 0); + if (status != B_OK) + return status; + + status = handle->info->io_scheduler->ScheduleRequest(&request); + if (status != B_OK) + return status; + + status = request.Wait(0, 0); + if (status == B_OK) + *_length = length; + else + dprintf("write(): request.Wait() returned: %s\n", strerror(status)); + + return status; +} + + +static status_t +virtio_block_io(void *cookie, io_request *request) +{ + CALLED(); + virtio_block_handle* handle = (virtio_block_handle*)cookie; + + return handle->info->io_scheduler->ScheduleRequest(request); +} + + +static status_t +virtio_block_ioctl(void* cookie, uint32 op, void* buffer, size_t length) +{ + CALLED(); + virtio_block_handle* handle = (virtio_block_handle*)cookie; + virtio_block_driver_info* info = handle->info; + + TRACE("ioctl(op = %ld)\n", op); + + switch (op) { + case B_GET_DEVICE_SIZE: + { + size_t size = info->capacity * info->block_size; + return user_memcpy(buffer, &size, sizeof(size_t)); + } + + case B_GET_GEOMETRY: + { + if (buffer == NULL /*|| length != sizeof(device_geometry)*/) + return B_BAD_VALUE; + + device_geometry geometry; + status_t status = get_geometry(handle, &geometry); + if (status != B_OK) + return status; + + return user_memcpy(buffer, &geometry, sizeof(device_geometry)); + } + + case B_GET_ICON_NAME: + return user_strlcpy((char*)buffer, "devices/drive-harddisk", + B_FILE_NAME_LENGTH); + + case B_GET_VECTOR_ICON: + { + // TODO: take device type into account! + device_icon iconData; + if (length != sizeof(device_icon)) + return B_BAD_VALUE; + if (user_memcpy(&iconData, buffer, sizeof(device_icon)) != B_OK) + return B_BAD_ADDRESS; + + if (iconData.icon_size >= (int32)sizeof(kDriveIcon)) { + if (user_memcpy(iconData.icon_data, kDriveIcon, + sizeof(kDriveIcon)) != B_OK) + return B_BAD_ADDRESS; + } + + iconData.icon_size = sizeof(kDriveIcon); + return user_memcpy(buffer, &iconData, sizeof(device_icon)); + } + + /*case B_FLUSH_DRIVE_CACHE: + return synchronize_cache(info);*/ + } + + return B_DEV_INVALID_IOCTL; +} + + +void +virtio_block_set_capacity(virtio_block_driver_info* info, uint64 capacity, + uint32 blockSize) +{ + TRACE("set_capacity(device = %p, capacity = %Ld, blockSize = %ld)\n", + info, capacity, blockSize); + + // get log2, if possible + uint32 blockShift = log2(blockSize); + + if ((1UL << blockShift) != blockSize) + blockShift = 0; + + info->capacity = capacity; + + if (info->block_size != blockSize) { + if (info->block_size != 0) { + ERROR("old %" B_PRId32 ", new %" B_PRId32 "\n", info->block_size, + blockSize); + panic("updating DMAResource not yet implemented..."); + } + + dma_restrictions restrictions; + memset(&restrictions, 0, sizeof(restrictions)); + if ((info->features & VIRTIO_BLK_F_SIZE_MAX) != 0) + restrictions.max_segment_size = info->config.size_max; + if ((info->features & VIRTIO_BLK_F_SEG_MAX) != 0) + restrictions.max_segment_count = info->config.seg_max; + + // TODO: we need to replace the DMAResource in our IOScheduler + status_t status = info->dma_resource->Init(restrictions, blockSize, + 1024, 32); + if (status != B_OK) + panic("initializing DMAResource failed: %s", strerror(status)); + + info->io_scheduler = new(std::nothrow) IOSchedulerSimple( + info->dma_resource); + if (info->io_scheduler == NULL) + panic("allocating IOScheduler failed."); + + // TODO: use whole device name here + status = info->io_scheduler->Init("virtio"); + if (status != B_OK) + panic("initializing IOScheduler failed: %s", strerror(status)); + + info->io_scheduler->SetCallback(do_io, info); + } + + info->block_size = blockSize; +} + + +// #pragma mark - driver module API + + +static float +virtio_block_supports_device(device_node *parent) +{ + CALLED(); + const char *bus; + uint16 deviceType; + + // make sure parent is really the Virtio bus manager + if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) + return -1; + + if (strcmp(bus, "virtio")) + return 0.0; + + // check whether it's really a Direct Access Device + if (sDeviceManager->get_attr_uint16(parent, VIRTIO_DEVICE_TYPE_ITEM, + &deviceType, true) != B_OK || deviceType != VIRTIO_DEVICE_ID_BLOCK) + return 0.0; + + TRACE("Virtio block device found!\n"); + + return 0.6; +} + + +static status_t +virtio_block_register_device(device_node *node) +{ + CALLED(); + + // ready to register + device_attr attrs[] = { + { NULL } + }; + + return sDeviceManager->register_node(node, VIRTIO_BLOCK_DRIVER_MODULE_NAME, + attrs, NULL, NULL); +} + + +static status_t +virtio_block_init_driver(device_node *node, void **cookie) +{ + CALLED(); + + virtio_block_driver_info* info = (virtio_block_driver_info*)malloc( + sizeof(virtio_block_driver_info)); + if (info == NULL) + return B_NO_MEMORY; + + memset(info, 0, sizeof(*info)); + + info->dma_resource = new(std::nothrow) DMAResource; + if (info->dma_resource == NULL) { + free(info); + return B_NO_MEMORY; + } + + info->sem_cb = create_sem(0, "virtio_block_cb"); + if (info->sem_cb < 0) { + delete info->dma_resource; + status_t status = info->sem_cb; + free(info); + return status; + } + info->node = node; + + *cookie = info; + return B_OK; +} + + +static void +virtio_block_uninit_driver(void *_cookie) +{ + CALLED(); + virtio_block_driver_info* info = (virtio_block_driver_info*)_cookie; + delete_sem(info->sem_cb); + free(info); +} + + +static status_t +virtio_block_register_child_devices(void* _cookie) +{ + CALLED(); + virtio_block_driver_info* info = (virtio_block_driver_info*)_cookie; + status_t status; + + int32 id = sDeviceManager->create_id(VIRTIO_BLOCK_DEVICE_ID_GENERATOR); + if (id < 0) + return id; + + char name[64]; + snprintf(name, sizeof(name), "disk/virtual/virtio_block/%" B_PRId32 "/raw", + id); + + status = sDeviceManager->publish_device(info->node, name, + VIRTIO_BLOCK_DEVICE_MODULE_NAME); + + return status; +} + + +// #pragma mark - + + +module_dependency module_dependencies[] = { + {B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager}, + {} +}; + +struct device_module_info sVirtioBlockDevice = { + { + VIRTIO_BLOCK_DEVICE_MODULE_NAME, + 0, + NULL + }, + + virtio_block_init_device, + virtio_block_uninit_device, + NULL, // remove, + + virtio_block_open, + virtio_block_close, + virtio_block_free, + virtio_block_read, + virtio_block_write, + virtio_block_io, + virtio_block_ioctl, + + NULL, // select + NULL, // deselect +}; + +struct driver_module_info sVirtioBlockDriver = { + { + VIRTIO_BLOCK_DRIVER_MODULE_NAME, + 0, + NULL + }, + + virtio_block_supports_device, + virtio_block_register_device, + virtio_block_init_driver, + virtio_block_uninit_driver, + virtio_block_register_child_devices, + NULL, // rescan + NULL, // removed +}; + +module_info* modules[] = { + (module_info*)&sVirtioBlockDriver, + (module_info*)&sVirtioBlockDevice, + NULL +}; + diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index f4d4f7164a..3f50e2ab16 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -340,17 +340,20 @@ intel_extreme_init(intel_info &info) // setup overlay registers - if (intel_allocate_memory(info, B_PAGE_SIZE, 0, - intel_uses_physical_overlay(*info.shared_info) + status_t status = intel_allocate_memory(info, B_PAGE_SIZE, 0, + intel_uses_physical_overlay(*info.shared_info) ? B_APERTURE_NEED_PHYSICAL : 0, - (addr_t*)&info.overlay_registers, - &info.shared_info->physical_overlay_registers) == B_OK) { + (addr_t*)&info.overlay_registers, + &info.shared_info->physical_overlay_registers); + if (status == B_OK) { info.shared_info->overlay_offset = (addr_t)info.overlay_registers - info.aperture_base; + init_overlay_registers(info.overlay_registers); + } else { + ERROR("error: could not allocate overlay memory! %s\n", + strerror(status)); } - init_overlay_registers(info.overlay_registers); - // Allocate hardware status page and the cursor memory if (intel_allocate_memory(info, B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL, diff --git a/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp b/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp index beb03523be..6816c78efd 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp @@ -124,7 +124,7 @@ const struct supported_device { {0x9513, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3850 X2"}, {0x9515, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3850"}, {0x9501, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3870"}, - {0x950F, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3870 X2"}, + {0x950F, 2, 0, RADEON_RV670, CHIP_STD | CHIP_X2, "Radeon HD 3870 X2"}, {0x9710, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4200"}, {0x9715, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4250"}, {0x9712, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4270"}, @@ -153,15 +153,15 @@ const struct supported_device { {0x944e, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4810"}, {0x944c, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4830"}, {0x9442, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4850"}, - {0x9443, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4850 X2"}, + {0x9443, 3, 1, RADEON_RV770, CHIP_STD | CHIP_X2, "Radeon HD 4850 X2"}, {0x94a1, 3, 1, RADEON_RV770, CHIP_IGP, "Radeon HD 4860"}, {0x9440, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4870"}, - {0x9441, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4870 X2"}, + {0x9441, 3, 1, RADEON_RV770, CHIP_STD | CHIP_X2, "Radeon HD 4870 X2"}, {0x9460, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4890"}, // From here on AMD no longer used numeric identifiers - // Marketing Names: Radeon HD 54xx ~ HD 63xx + // Marketing Names: Radeon HD 5450 - HD 6320 // Introduced: 2009 // Codename: Evergreen // Process: 40 nm @@ -186,7 +186,8 @@ const struct supported_device { {0x6899, 4, 0, RADEON_CYPRESS, CHIP_STD, "Radeon HD 5850"}, {0x6898, 4, 0, RADEON_CYPRESS, CHIP_STD, "Radeon HD 5870"}, // Hemlock - {0x689c, 4, 0, RADEON_HEMLOCK, CHIP_STD, "Radeon HD 5900"}, + {0x689c, 4, 0, RADEON_HEMLOCK, CHIP_STD | CHIP_X2, "Radeon HD 5900 X2"}, + {0x689d, 4, 0, RADEON_HEMLOCK, CHIP_STD | CHIP_X2, "Radeon HD 5900 X2"}, // Fusion APUS // Palm {0x9804, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6250"}, @@ -209,7 +210,7 @@ const struct supported_device { {0x9644, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD 6410D"}, {0x9645, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD SUMO2 M"}, - // Radeon HD 64xx - HD 69xx + // Radeon HD 6450 - HD 7670 // Introduced: 2010 // Codename: Nothern Islands // Process: 40 nm @@ -244,6 +245,7 @@ const struct supported_device { {0x6750, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6500"}, {0x6758, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6670"}, {0x6759, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6570/7570"}, + {0x6850, 6, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 7570"}, // Barts {0x673e, 5, 0, RADEON_BARTS, CHIP_STD, "Radeon HD 6790"}, {0x6739, 5, 0, RADEON_BARTS, CHIP_STD, "Radeon HD 6850"}, @@ -266,12 +268,10 @@ const struct supported_device { // Antilles (Top, Dual GPU) {0x671d, 5, 0, RADEON_ANTILLES, CHIP_STD, "Radeon HD 6990"}, - // Marketing Names: Radeon HD 74xx - HD 79xx + // Marketing Names: Radeon HD 7750 - HD 79xx // Introduced: Late 2011 // Codename: Southern Islands // Process: 28 nm - // Lombok? - {0x6850, 6, 0, RADEON_LOMBOK, CHIP_MOBILE, "Radeon HD 7570"}, // Cape Verde (TODO: Need to find friendly names) {0x6820, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"}, {0x6821, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"}, @@ -292,6 +292,13 @@ const struct supported_device { {0x683b, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"}, {0x683f, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD 7750"}, {0x683d, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD 7770"}, + // Bonaire (TODO: Need to find friendly names) + {0x6649, 6, 0, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"}, + {0x6650, 6, 0, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"}, + {0x6651, 6, 0, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"}, + {0x6658, 6, 0, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"}, + {0x665c, 6, 0, RADEON_BONAIRE, CHIP_STD, "Radeon HD 7790"}, + {0x665d, 6, 0, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"}, // Pitcairn (TODO: Need to find friendly names) {0x6800, 6, 0, RADEON_PITCAIRN, CHIP_MOBILE, "Radeon HD 7970"}, {0x6801, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"}, @@ -312,8 +319,25 @@ const struct supported_device { {0x679f, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD Tahiti"}, {0x679a, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7950"}, {0x6798, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7970"}, - // New Zealand (Top, Dual GPU) - {0x6799, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7990"} + {0x6799, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7990"}, + + // Marketing Names: Radeon HD 83xx - HD 89xx + // Introduced: Late 2013 + // Codename: Sea Islands + // Process: 28 nm + // Oland DCE 6,4 + // Hainan NO DCE? + // Curacao ???? + + // Marketing Names: Radeon HD 9xxx - HD 9xxx + // Introduced: 2014? + // Codename: Volcanic Islands + // Process: 20 nm + + // Marketing Names: Radeon HD 9xxx - HD 9xxx + // Introduced: 2015? + // Codename: Pirate Islands + // Process: ?? nm }; diff --git a/src/add-ons/kernel/drivers/graphics/radeon_hd/sensors.cpp b/src/add-ons/kernel/drivers/graphics/radeon_hd/sensors.cpp index 7c6fb11aa8..607b1cc76a 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon_hd/sensors.cpp +++ b/src/add-ons/kernel/drivers/graphics/radeon_hd/sensors.cpp @@ -26,7 +26,7 @@ radeon_thermal_query(radeon_info &info) uint32 rawTemp = 0; int32 finalTemp = 0; - if (info.chipsetID >= RADEON_LOMBOK) { + if (info.chipsetID >= RADEON_CAPEVERDE) { rawTemp = (read32(info.registers + SI_CG_MULT_THERMAL_STATUS) & SI_CTF_TEMP_MASK) >> SI_CTF_TEMP_SHIFT; diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index 68c4e0353b..a6aceca9ce 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -2013,7 +2013,7 @@ BlockAllocator::_CheckInodeBlocks(Inode* inode, const char* name) fCheckCookie->control.stats.double_indirect_block_runs++; fCheckCookie->control.stats.blocks_in_double_indirect += runs[index % runsPerBlock].Length(); - } while ((++index % runsPerArray) != 0); + } while ((++index % runsPerBlock) != 0); } fCheckCookie->control.stats.double_indirect_array_blocks++; diff --git a/src/add-ons/kernel/file_systems/netfs/client/ShareAttrDir.cpp b/src/add-ons/kernel/file_systems/netfs/client/ShareAttrDir.cpp index a92a01facc..febc358ea5 100644 --- a/src/add-ons/kernel/file_systems/netfs/client/ShareAttrDir.cpp +++ b/src/add-ons/kernel/file_systems/netfs/client/ShareAttrDir.cpp @@ -395,7 +395,7 @@ ShareAttrDir::GetAttribute(const char* name) const return attribute; } - return false; + return NULL; } // GetFirstAttribute diff --git a/src/add-ons/kernel/file_systems/netfs/server/AttributeDirectory.cpp b/src/add-ons/kernel/file_systems/netfs/server/AttributeDirectory.cpp index 07b549dda0..8023ed2f2b 100644 --- a/src/add-ons/kernel/file_systems/netfs/server/AttributeDirectory.cpp +++ b/src/add-ons/kernel/file_systems/netfs/server/AttributeDirectory.cpp @@ -329,7 +329,7 @@ AttributeDirectory::GetAttribute(const char* name) const return attribute; } - return false; + return NULL; } // GetFirstAttribute diff --git a/src/add-ons/kernel/file_systems/nfs4/Cookie.cpp b/src/add-ons/kernel/file_systems/nfs4/Cookie.cpp index 1fbfe5cc6b..940a5d9ff3 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Cookie.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Cookie.cpp @@ -67,8 +67,9 @@ LockInfo::operator==(const LockInfo& lock) const } -Cookie::Cookie() +Cookie::Cookie(FileSystem* fileSystem) : + fFileSystem(fileSystem), fRequests(NULL), fSnoozeCancel(create_sem(1, NULL)) { @@ -144,8 +145,16 @@ Cookie::CancelAll() } -OpenFileCookie::OpenFileCookie() +OpenStateCookie::OpenStateCookie(FileSystem* fileSystem) : + Cookie(fileSystem) +{ +} + + +OpenFileCookie::OpenFileCookie(FileSystem* fileSystem) + : + OpenStateCookie(fileSystem), fLocks(NULL) { } @@ -173,9 +182,23 @@ OpenFileCookie::RemoveLock(LockInfo* lock, LockInfo* prev) } +OpenDirCookie::OpenDirCookie(FileSystem* fileSystem) + : + Cookie(fileSystem) +{ +} + + OpenDirCookie::~OpenDirCookie() { if (fSnapshot != NULL) fSnapshot->ReleaseReference(); } + +OpenAttrCookie::OpenAttrCookie(FileSystem* fileSystem) + : + OpenStateCookie(fileSystem) +{ +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/Cookie.h b/src/add-ons/kernel/file_systems/nfs4/Cookie.h index a3d36c9c8c..056fb5d845 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Cookie.h +++ b/src/add-ons/kernel/file_systems/nfs4/Cookie.h @@ -66,7 +66,7 @@ struct Cookie { sem_id fSnoozeCancel; - Cookie(); + Cookie(FileSystem* fileSystem); virtual ~Cookie(); status_t RegisterRequest(RPC::Request* req); @@ -77,6 +77,8 @@ struct Cookie { struct OpenStateCookie : public Cookie { OpenState* fOpenState; uint32 fMode; + + OpenStateCookie(FileSystem* fileSystem); }; struct OpenFileCookie : public OpenStateCookie { @@ -85,7 +87,7 @@ struct OpenFileCookie : public OpenStateCookie { void AddLock(LockInfo* lock); void RemoveLock(LockInfo* lock, LockInfo* prev); - OpenFileCookie(); + OpenFileCookie(FileSystem* fileSystem); }; struct OpenDirCookie : public Cookie { @@ -96,10 +98,13 @@ struct OpenDirCookie : public Cookie { bool fAttrDir; + OpenDirCookie(FileSystem* fileSystem); ~OpenDirCookie(); }; -struct OpenAttrCookie : public OpenStateCookie { }; +struct OpenAttrCookie : public OpenStateCookie { + OpenAttrCookie(FileSystem* fileSystem); +}; #endif // COOKIE_H diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index be69f682c1..9e2f687686 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -749,7 +749,7 @@ Inode::AcquireLock(OpenFileCookie* cookie, const struct flock* lock, if (owner == NULL) return B_NO_MEMORY; - LockInfo* linfo = new LockInfo(owner); + LockInfo* linfo = new(std::nothrow) LockInfo(owner); if (linfo == NULL) return B_NO_MEMORY; locker.Unlock(); diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp index eef37a619a..4d78e096fe 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp @@ -36,7 +36,6 @@ Inode::OpenDir(OpenDirCookie* cookie) if (result != B_OK) return result; - cookie->fFileSystem = fFileSystem; cookie->fSpecial = 0; cookie->fSnapshot = NULL; cookie->fCurrent = NULL; @@ -52,7 +51,6 @@ Inode::OpenAttrDir(OpenDirCookie* cookie) { ASSERT(cookie != NULL); - cookie->fFileSystem = fFileSystem; cookie->fSpecial = 0; cookie->fSnapshot = NULL; cookie->fCurrent = NULL; diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp index d591fddda2..4b7b692ac9 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp @@ -84,7 +84,6 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie, } cookie->fOpenState = state; - cookie->fFileSystem = fFileSystem; *id = FileIdToInoT(state->fInfo.fFileId); @@ -168,7 +167,6 @@ Inode::Open(int mode, OpenFileCookie* cookie) file_cache_set_size(fFileCache, 0); } - cookie->fFileSystem = fFileSystem; cookie->fMode = mode; cookie->fLocks = NULL; @@ -262,7 +260,6 @@ Inode::OpenAttr(const char* _name, int mode, OpenAttrCookie* cookie, fFileSystem->AddOpenFile(state); cookie->fOpenState = state; - cookie->fFileSystem = fFileSystem; cookie->fMode = mode; if (data.fType != OPEN_DELEGATE_NONE) { diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp index af9b47d07d..1a3ab1f4a2 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp @@ -1004,18 +1004,16 @@ NFS4Inode::ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie, ArrayDeleter beforeDeleter(before); result = reply.ReadDir(dirCookie, dirCookieVerf, dirents, count, eof); - if (result != B_OK) { - delete[] before; + if (result != B_OK) return result; - } + ArrayDeleter entriesDeleter(*dirents); AttrValue* after; result = reply.GetAttr(&after, &attrCount); - if (result != B_OK) { - delete[] before; + if (result != B_OK) return result; - } + ArrayDeleter afterDeleter(after); if ((*change == 0 diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp index c7f7827a2e..2f40d6eac1 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp @@ -17,9 +17,9 @@ static inline bigtime_t RetryDelay(uint32 attempt, uint32 leaseTime = 0) { - attempt = min_c(attempt, sizeof(bigtime_t) * 8); + attempt = min_c(attempt, 10); - bigtime_t delay = (1 << (attempt - 1)) * 100000; + bigtime_t delay = (bigtime_t(1) << (attempt - 1)) * 100000; if (leaseTime != 0) delay = min_c(delay, sSecToBigTime(leaseTime)); return delay; @@ -32,7 +32,6 @@ NFS4Object::HandleErrors(uint32& attempt, uint32 nfs4Error, RPC::Server* server, { // No request send by the client should cause any of the following errors. ASSERT(nfs4Error != NFS4ERR_CLID_INUSE); - ASSERT(nfs4Error != NFS4ERR_NOFILEHANDLE); ASSERT(nfs4Error != NFS4ERR_BAD_STATEID); ASSERT(nfs4Error != NFS4ERR_RESTOREFH); ASSERT(nfs4Error != NFS4ERR_LOCKS_HELD); @@ -60,6 +59,9 @@ NFS4Object::HandleErrors(uint32& attempt, uint32 nfs4Error, RPC::Server* server, // resource is locked, we need to wait case NFS4ERR_DENIED: + if (cookie == NULL) + return false; + if (sequence != NULL) fFileSystem->OpenOwnerSequenceUnlock(*sequence); diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.h index 624b0fe26a..c0f2abfcb0 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.h @@ -61,7 +61,6 @@ private: uint32 fLeaseTime; uint64 fClientId; - bool fClientIdInit; time_t fClientIdLastUse; mutex fClientIdLock; diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.cpp b/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.cpp index fa371a0ffe..0c448480bf 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.cpp @@ -306,7 +306,8 @@ CallbackServer::ConnectionThread(ConnectionEntry* entry) return result; } - CallbackRequest* request = new CallbackRequest(buffer, size); + CallbackRequest* request + = new(std::nothrow) CallbackRequest(buffer, size); if (request == NULL) { free(buffer); continue; diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.h b/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.h index fce7354b02..5e6172592e 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.h +++ b/src/add-ons/kernel/file_systems/nfs4/RPCCallbackServer.h @@ -87,6 +87,8 @@ CallbackServer::LocalID() PeerAddress address; ASSERT(fListener != NULL); + + memset(&address, 0, sizeof(address)); fListener->GetLocalAddress(&address); return address; } diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp index ed9dee0615..24443e669f 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp @@ -110,6 +110,8 @@ RootInode::_UpdateInfo(bool force) if (ioSize == LONGLONG_MAX) ioSize = 32768; + if (ioSize == 0) + ioSize = 4096; fInfoCache.io_size = ioSize; fInfoCache.block_size = ioSize; fIOSize = ioSize; @@ -203,10 +205,12 @@ RootInode::GetLocations(AttrValue** attrv) result = reply.GetAttr(attrv, &count); if (result != B_OK) return result; - if (count < 1) + if (count < 1) { + delete *attrv; return B_ERROR; - return B_OK; + } + return B_OK; } while (true); return B_OK; diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp index 522a9eb477..b8f7294dff 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -752,7 +752,9 @@ static status_t nfs4_create(fs_volume* volume, fs_vnode* dir, const char* name, int openMode, int perms, void** _cookie, ino_t* _newVnodeID) { - OpenFileCookie* cookie = new OpenFileCookie; + FileSystem* fs = reinterpret_cast(volume->private_volume); + + OpenFileCookie* cookie = new OpenFileCookie(fs); if (cookie == NULL) return B_NO_MEMORY; *_cookie = cookie; @@ -766,7 +768,6 @@ nfs4_create(fs_volume* volume, fs_vnode* dir, const char* name, int openMode, if (inode == NULL) return B_ENTRY_NOT_FOUND; - FileSystem* fs = reinterpret_cast(volume->private_volume); MutexLocker createLocker(fs->CreateFileLock()); OpenDelegationData data; @@ -826,7 +827,8 @@ nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie) return B_OK; } - OpenFileCookie* cookie = new OpenFileCookie; + FileSystem* fs = reinterpret_cast(volume->private_volume); + OpenFileCookie* cookie = new OpenFileCookie(fs); if (cookie == NULL) return B_NO_MEMORY; *_cookie = cookie; @@ -1003,7 +1005,8 @@ nfs4_remove_dir(fs_volume* volume, fs_vnode* parent, const char* name) static status_t nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie) { - OpenDirCookie* cookie = new(std::nothrow) OpenDirCookie; + FileSystem* fs = reinterpret_cast(volume->private_volume); + OpenDirCookie* cookie = new(std::nothrow) OpenDirCookie(fs); if (cookie == NULL) return B_NO_MEMORY; *_cookie = cookie; @@ -1087,7 +1090,8 @@ nfs4_rewind_dir(fs_volume* volume, fs_vnode* vnode, void* _cookie) static status_t nfs4_open_attr_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie) { - OpenDirCookie* cookie = new(std::nothrow) OpenDirCookie; + FileSystem* fs = reinterpret_cast(volume->private_volume); + OpenDirCookie* cookie = new(std::nothrow) OpenDirCookie(fs); if (cookie == NULL) return B_NO_MEMORY; *_cookie = cookie; @@ -1148,7 +1152,8 @@ nfs4_create_attr(fs_volume* volume, fs_vnode* vnode, const char* name, if (inode == NULL) return B_ENTRY_NOT_FOUND; - OpenAttrCookie* cookie = new OpenAttrCookie; + FileSystem* fs = reinterpret_cast(volume->private_volume); + OpenAttrCookie* cookie = new OpenAttrCookie(fs); if (cookie == NULL) return B_NO_MEMORY; *_cookie = cookie; @@ -1172,7 +1177,8 @@ nfs4_open_attr(fs_volume* volume, fs_vnode* vnode, const char* name, if (inode == NULL) return B_ENTRY_NOT_FOUND; - OpenAttrCookie* cookie = new OpenAttrCookie; + FileSystem* fs = reinterpret_cast(volume->private_volume); + OpenAttrCookie* cookie = new OpenAttrCookie(fs); if (cookie == NULL) return B_NO_MEMORY; *_cookie = cookie; diff --git a/src/add-ons/kernel/network/protocols/udp/udp.cpp b/src/add-ons/kernel/network/protocols/udp/udp.cpp index 9fd4327604..97926b1950 100644 --- a/src/add-ons/kernel/network/protocols/udp/udp.cpp +++ b/src/add-ons/kernel/network/protocols/udp/udp.cpp @@ -965,6 +965,8 @@ status_t UdpEndpoint::Close() { TRACE_EP("Close()"); + fSocket->error = EBADF; + WakeAll(); return B_OK; } diff --git a/src/add-ons/kernel/network/stack/link.cpp b/src/add-ons/kernel/network/stack/link.cpp index a1341aafc7..c88f19b497 100644 --- a/src/add-ons/kernel/network/stack/link.cpp +++ b/src/add-ons/kernel/network/stack/link.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2013, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -467,8 +467,10 @@ link_control(net_protocol* _protocol, int level, int option, void* value, if (interface == NULL) return B_DEVICE_NOT_FOUND; - if (user_memcpy(&request, value, sizeof(ifmediareq)) != B_OK) + if (user_memcpy(&request, value, sizeof(ifmediareq)) != B_OK) { + put_device_interface(interface); return B_BAD_ADDRESS; + } // TODO: see above. if (interface->device->module->control(interface->device, @@ -478,6 +480,7 @@ link_control(net_protocol* _protocol, int level, int option, void* value, request.ifm_active = request.ifm_current = interface->device->media; } + put_device_interface(interface); return user_memcpy(value, &request, sizeof(struct ifmediareq)); } diff --git a/src/add-ons/translators/gif/SavePalette.cpp b/src/add-ons/translators/gif/SavePalette.cpp index eb1ffb1284..7f8d66d493 100644 --- a/src/add-ons/translators/gif/SavePalette.cpp +++ b/src/add-ons/translators/gif/SavePalette.cpp @@ -244,7 +244,7 @@ SavePalette::SavePalette(BBitmap *bitmap, int32 maxSizeInBits) fSize(0), fSizeInBits(0), fMode(OPTIMAL_PALETTE), - fTransparentMode(fTransparentMode), + fTransparentMode(NO_TRANSPARENCY), fTransparentIndex(-1), fBackgroundIndex(0), fFatalError(pal == NULL) diff --git a/src/add-ons/translators/sgi/SGIView.cpp b/src/add-ons/translators/sgi/SGIView.cpp index aab159056a..3ce90e245f 100644 --- a/src/add-ons/translators/sgi/SGIView.cpp +++ b/src/add-ons/translators/sgi/SGIView.cpp @@ -30,6 +30,9 @@ // DEALINGS IN THE SOFTWARE. /*****************************************************************************/ + +#include "SGIView.h" + #include #include @@ -46,13 +49,14 @@ #include "SGIImage.h" #include "SGITranslator.h" -#include "SGIView.h" + const char* author = "Stephan Aßmus, "; #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "SGIView" + // add_menu_item void add_menu_item(BMenu* menu, @@ -67,19 +71,7 @@ add_menu_item(BMenu* menu, menu->AddItem(item); } -// --------------------------------------------------------------- -// Constructor -// -// Sets up the view settings -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- + SGIView::SGIView(const char* name, uint32 flags, TranslatorSettings* settings) : BView(name, flags, new BGroupLayout(B_VERTICAL)), @@ -92,16 +84,16 @@ SGIView::SGIView(const char* name, uint32 flags, TranslatorSettings* settings) // create the menu items with the various compression methods add_menu_item(menu, SGI_COMP_NONE, B_TRANSLATE("None"), currentCompression); -// menu->AddSeparatorItem(); + //menu->AddSeparatorItem(); add_menu_item(menu, SGI_COMP_RLE, B_TRANSLATE("RLE"), currentCompression); -// DON'T turn this on, it's so slow that I didn't wait long enough -// the one time I tested this. So I don't know if the code even works. -// Supposedly, this would look for an already written scanline, and -// modify the scanline tables so that the current row is not written -// at all... + // DON'T turn this on, it's so slow that I didn't wait long enough + // the one time I tested this. So I don't know if the code even works. + // Supposedly, this would look for an already written scanline, and + // modify the scanline tables so that the current row is not written + // at all... -// add_menu_item(menu, SGI_COMP_ARLE, "Agressive RLE", currentCompression); + //add_menu_item(menu, SGI_COMP_ARLE, "Agressive RLE", currentCompression); fCompressionMF = new BMenuField("compression", B_TRANSLATE("Use compression:"), menu); @@ -138,14 +130,17 @@ SGIView::SGIView(const char* name, uint32 flags, TranslatorSettings* settings) .SetInsets(padding) .Add(titleView) .Add(detailView) - .Add(fCompressionMF) + .AddGroup(B_HORIZONTAL) + .Add(fCompressionMF) + .AddGlue() + .End() .Add(infoView) .AddGlue(); BFont font; GetFont(&font); - SetExplicitPreferredSize( - BSize((font.Size() * 390) / 12, (font.Size() * 180) / 12)); + SetExplicitPreferredSize(BSize((font.Size() * 390) / 12, + (font.Size() * 180) / 12)); // TODO: remove this workaround for ticket #4217 infoView->SetExplicitPreferredSize( @@ -155,37 +150,19 @@ SGIView::SGIView(const char* name, uint32 flags, TranslatorSettings* settings) } -// --------------------------------------------------------------- -// Destructor -// -// Does nothing -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- SGIView::~SGIView() { fSettings->Release(); } -// --------------------------------------------------------------- -// MessageReceived -// -// Handles state changes of the Compression menu field -// -// Preconditions: -// -// Parameters: area, not used -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- + +void +SGIView::AllAttached() +{ + fCompressionMF->Menu()->SetTargetForItems(this); +} + + void SGIView::MessageReceived(BMessage* message) { @@ -196,30 +173,9 @@ SGIView::MessageReceived(BMessage* message) fSettings->SetGetInt32(SGI_SETTING_COMPRESSION, &value); fSettings->SaveSettings(); } - fCompressionMF->ResizeToPreferred(); break; } default: BView::MessageReceived(message); } } - -// --------------------------------------------------------------- -// AllAttached -// -// sets the target for the controls controlling the configuration -// -// Preconditions: -// -// Parameters: area, not used -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void -SGIView::AllAttached() -{ - fCompressionMF->Menu()->SetTargetForItems(this); -} - diff --git a/src/add-ons/translators/sgi/SGIView.h b/src/add-ons/translators/sgi/SGIView.h index c90797d8cc..c3ebda93e7 100644 --- a/src/add-ons/translators/sgi/SGIView.h +++ b/src/add-ons/translators/sgi/SGIView.h @@ -29,36 +29,38 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /*****************************************************************************/ - #ifndef SGIVIEW_H #define SGIVIEW_H + #include #include "TranslatorSettings.h" + class BMenuField; + class SGIView : public BView { public: - SGIView(const char* name, uint32 flags, TranslatorSettings* settings); - // sets up the view - - ~SGIView(); - // releases the SGITranslator settings + SGIView(const char* name, uint32 flags, TranslatorSettings* settings); + // sets up the view - virtual void AllAttached(); - virtual void MessageReceived(BMessage* message); + ~SGIView(); + // releases the SGITranslator settings + + virtual void AllAttached(); + virtual void MessageReceived(BMessage* message); enum { MSG_COMPRESSION_CHANGED = 'cmch', }; private: - BMenuField* fCompressionMF; + BMenuField* fCompressionMF; - TranslatorSettings* fSettings; - // the actual settings for the translator, - // shared with the translator + TranslatorSettings* fSettings; + // the actual settings for the translator, shared with the translator }; + #endif // #ifndef SGIVIEW_H diff --git a/src/add-ons/translators/tiff/TIFFView.cpp b/src/add-ons/translators/tiff/TIFFView.cpp index 9b845ab86b..64071ba951 100644 --- a/src/add-ons/translators/tiff/TIFFView.cpp +++ b/src/add-ons/translators/tiff/TIFFView.cpp @@ -30,6 +30,9 @@ // DEALINGS IN THE SOFTWARE. /*****************************************************************************/ + +#include "TIFFView.h" + #include #include @@ -46,7 +49,6 @@ #include "TIFFTranslator.h" #include "TranslatorSettings.h" -#include "TIFFView.h" #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "TIFFView" @@ -66,22 +68,11 @@ add_menu_item(BMenu* menu, menu->AddItem(item); } -// --------------------------------------------------------------- -// Constructor -// -// Sets up the view settings -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -TIFFView::TIFFView(const char *name, uint32 flags, - TranslatorSettings *settings) - : BView(name, flags) + +TIFFView::TIFFView(const char* name, uint32 flags, + TranslatorSettings* settings) + : + BView(name, flags) { fSettings = settings; @@ -102,12 +93,12 @@ TIFFView::TIFFView(const char *name, uint32 flags, int16 i = 1; fLibTIFF[0] = new BStringView(NULL, B_TRANSLATE("TIFF Library:")); char libtiff[] = TIFFLIB_VERSION_STR; - char *tok = strtok(libtiff, "\n"); - while (i < 5 && tok) { + char* tok = strtok(libtiff, "\n"); + while (i < 5 && tok) { fLibTIFF[i] = new BStringView(NULL, tok); tok = strtok(NULL, "\n"); i++; - } + } BPopUpMenu* menu = new BPopUpMenu("pick compression"); @@ -123,66 +114,54 @@ TIFFView::TIFFView(const char *name, uint32 flags, add_menu_item(menu, COMPRESSION_LZW, B_TRANSLATE("LZW"), currentCompression); -// TODO: the disabled compression modes are not configured in libTIFF -// menu->AddSeparatorItem(); -// add_menu_item(menu, COMPRESSION_JPEG, "JPEG", currentCompression); -// TODO ? - strip encoding is not implemented in libTIFF for this compression -// add_menu_item(menu, COMPRESSION_JP2000, "JPEG2000", currentCompression); + // TODO: the disabled compression modes are not configured in libTIFF + // menu->AddSeparatorItem(); + // add_menu_item(menu, COMPRESSION_JPEG, "JPEG", currentCompression); + // TODO ? - strip encoding is not implemented in libTIFF for this compression + // add_menu_item(menu, COMPRESSION_JP2000, "JPEG2000", currentCompression); - fCompressionMF = new BMenuField(B_TRANSLATE("Use Compression:"), menu); + fCompressionMF = new BMenuField(B_TRANSLATE("Use compression:"), menu); - // Build the layout + // Build the layout BLayoutBuilder::Group<>(this, B_VERTICAL, 7) .SetInsets(5) - .Add(fTitle) - .Add(fDetail) - .AddGlue() - .Add(fCompressionMF) - .AddGlue() - .Add(fLibTIFF[0]) - .Add(fLibTIFF[1]) - .Add(fLibTIFF[2]) - .Add(fLibTIFF[3]) - // Theses 4 adding above work because we know there are 4 strings - // but it's fragile: one string less in the library version and the application breaks + .Add(fTitle) + .Add(fDetail) + .AddGlue() + .AddGroup(B_HORIZONTAL) + .Add(fCompressionMF) + .AddGlue() + .End() + .AddGlue() + .Add(fLibTIFF[0]) + .Add(fLibTIFF[1]) + .Add(fLibTIFF[2]) + .Add(fLibTIFF[3]) + // Theses 4 adding above work because we know there are 4 strings + // but it's fragile: one string less in the library version and the + // application breaks .AddGlue(); - BFont font; - GetFont(&font); - SetExplicitPreferredSize(BSize((font.Size() * 350)/12, (font.Size() * 200)/12)); + BFont font; + GetFont(&font); + SetExplicitPreferredSize( + BSize((font.Size() * 350)/12, (font.Size() * 200)/12)); } -// --------------------------------------------------------------- -// Destructor -// -// Does nothing -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- + TIFFView::~TIFFView() { fSettings->Release(); } -// --------------------------------------------------------------- -// MessageReceived -// -// Handles state changes of the Compression menu field -// -// Preconditions: -// -// Parameters: area, not used -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- + +void +TIFFView::AllAttached() +{ + fCompressionMF->Menu()->SetTargetForItems(this); +} + + void TIFFView::MessageReceived(BMessage* message) { @@ -199,26 +178,3 @@ TIFFView::MessageReceived(BMessage* message) BView::MessageReceived(message); } } - -// --------------------------------------------------------------- -// AllAttached -// -// sets the target for the controls controlling the configuration -// -// Preconditions: -// -// Parameters: area, not used -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void -TIFFView::AllAttached() -{ - fCompressionMF->Menu()->SetTargetForItems(this); - fCompressionMF->SetDivider(fCompressionMF->StringWidth(fCompressionMF->Label()) + 3); - fCompressionMF->ResizeToPreferred(); -} - - diff --git a/src/add-ons/translators/tiff/TIFFView.h b/src/add-ons/translators/tiff/TIFFView.h index 51e2c428aa..69754feaf5 100644 --- a/src/add-ons/translators/tiff/TIFFView.h +++ b/src/add-ons/translators/tiff/TIFFView.h @@ -28,39 +28,40 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /*****************************************************************************/ - #ifndef TIFFVIEW_H #define TIFFVIEW_H + #include #include #include #include "TranslatorSettings.h" + class TIFFView : public BView { public: - TIFFView(const char *name, uint32 flags, TranslatorSettings *settings); - // sets up the view - - ~TIFFView(); - // releases the TIFFTranslator settings + TIFFView(const char* name, uint32 flags, TranslatorSettings* settings); + // sets up the view - virtual void AllAttached(); - virtual void MessageReceived(BMessage *message); + ~TIFFView(); + // releases the TIFFTranslator settings + + virtual void AllAttached(); + virtual void MessageReceived(BMessage* message); enum { MSG_COMPRESSION_CHANGED = 'cmch', }; private: - BStringView* fTitle; - BStringView* fDetail; - BStringView* fLibTIFF[5]; - BMenuField* fCompressionMF; + BStringView* fTitle; + BStringView* fDetail; + BStringView* fLibTIFF[5]; + BMenuField* fCompressionMF; - TranslatorSettings *fSettings; - // the actual settings for the translator, - // shared with the translator + TranslatorSettings* fSettings; + // the actual settings for the translator, shared with the translator }; + #endif // #ifndef TIFFVIEW_H diff --git a/src/apps/debuganalyzer/gui/table/Table.cpp b/src/apps/debuganalyzer/gui/table/Table.cpp index 70819add04..2eb7b93cc3 100644 --- a/src/apps/debuganalyzer/gui/table/Table.cpp +++ b/src/apps/debuganalyzer/gui/table/Table.cpp @@ -63,6 +63,12 @@ TableModelListener::TableRowsChanged(TableModel* model, int32 rowIndex, } +void +TableModelListener::TableModelReset(TableModel* model) +{ +} + + // #pragma mark - TableModel @@ -118,6 +124,17 @@ TableModel::NotifyRowsChanged(int32 rowIndex, int32 count) } +void +TableModel::NotifyTableModelReset() +{ + int32 listenerCount = fListeners.CountItems(); + for (int32 i = listenerCount - 1; i >= 0; i--) { + TableModelListener* listener = fListeners.ItemAt(i); + listener->TableModelReset(this); + } +} + + // #pragma mark - TableSelectionModel TableSelectionModel::TableSelectionModel(Table* table) @@ -616,6 +633,12 @@ Table::TableRowsAdded(TableModel* model, int32 rowIndex, int32 count) void Table::TableRowsRemoved(TableModel* model, int32 rowIndex, int32 count) { + if (rowIndex == 0 && count == fRows.CountItems()) { + fRows.MakeEmpty(); + Clear(); + return; + } + for (int32 i = rowIndex + count - 1; i >= rowIndex; i--) { if (BRow* row = fRows.RemoveItemAt(i)) { RemoveRow(row); @@ -639,6 +662,14 @@ Table::TableRowsChanged(TableModel* model, int32 rowIndex, int32 count) } +void +Table::TableModelReset(TableModel* model) +{ + Clear(); + TableRowsAdded(model, 0, model->CountRows()); +} + + void Table::ItemInvoked() { diff --git a/src/apps/debuganalyzer/gui/table/Table.h b/src/apps/debuganalyzer/gui/table/Table.h index 1018849c85..99abf6853e 100644 --- a/src/apps/debuganalyzer/gui/table/Table.h +++ b/src/apps/debuganalyzer/gui/table/Table.h @@ -29,6 +29,7 @@ public: int32 rowIndex, int32 count); virtual void TableRowsChanged(TableModel* model, int32 rowIndex, int32 count); + virtual void TableModelReset(TableModel* model); }; @@ -51,6 +52,7 @@ protected: void NotifyRowsAdded(int32 rowIndex, int32 count); void NotifyRowsRemoved(int32 rowIndex, int32 count); void NotifyRowsChanged(int32 rowIndex, int32 count); + void NotifyTableModelReset(); protected: ListenerList fListeners; @@ -154,6 +156,7 @@ private: int32 rowIndex, int32 count); virtual void TableRowsChanged(TableModel* model, int32 rowIndex, int32 count); + virtual void TableModelReset(TableModel* model); private: class Column; diff --git a/src/apps/debuganalyzer/gui/table/TreeTable.cpp b/src/apps/debuganalyzer/gui/table/TreeTable.cpp index 851342a4cd..c69149ed9b 100644 --- a/src/apps/debuganalyzer/gui/table/TreeTable.cpp +++ b/src/apps/debuganalyzer/gui/table/TreeTable.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2012, Rene Gollent, rene@gollent.com. + * Copyright 2012-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -156,6 +156,12 @@ TreeTableModelListener::TableNodesChanged(TreeTableModel* model, } +void +TreeTableModelListener::TableModelReset(TreeTableModel* model) +{ +} + + // #pragma mark - TreeTableModel @@ -227,6 +233,16 @@ TreeTableModel::NotifyNodesChanged(const TreeTablePath& path, int32 childIndex, } +void +TreeTableModel::NotifyTableModelReset() +{ + int32 listenerCount = fListeners.CountItems(); + for (int32 i = listenerCount - 1; i >= 0; i--) { + TreeTableModelListener* listener = fListeners.ItemAt(i); + listener->TableModelReset(this); + } +} + // #pragma mark - TreeTableToolTipProvider @@ -965,6 +981,15 @@ TreeTable::TableNodesChanged(TreeTableModel* model, const TreeTablePath& path, } +void +TreeTable::TableModelReset(TreeTableModel* model) +{ + _RemoveChildRows(fRootNode, 0, fRootNode->CountChildren()); + _AddChildRows(fRootNode, 0, fModel->CountChildren( + fModel->Root()), fModel->CountColumns()); +} + + void TreeTable::ExpandOrCollapse(BRow* _row, bool expand) { @@ -1038,6 +1063,14 @@ void TreeTable::_RemoveChildRows(TreeTableNode* parentNode, int32 childIndex, int32 count) { + // check if the removal request would in effect remove all + // existing nodes. + if (parentNode == fRootNode && childIndex == 0 + && count == parentNode->CountChildren()) { + Clear(); + return; + } + for (int32 i = childIndex + count - 1; i >= childIndex; i--) { if (TreeTableNode* child = parentNode->RemoveChild(i)) { int32 childCount = child->CountChildren(); diff --git a/src/apps/debuganalyzer/gui/table/TreeTable.h b/src/apps/debuganalyzer/gui/table/TreeTable.h index b006e083f1..81d8924a7a 100644 --- a/src/apps/debuganalyzer/gui/table/TreeTable.h +++ b/src/apps/debuganalyzer/gui/table/TreeTable.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2012, Rene Gollent, rene@gollent.com. + * Copyright 2012-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TREE_TABLE_H @@ -61,6 +61,7 @@ public: virtual void TableNodesChanged(TreeTableModel* model, const TreeTablePath& path, int32 childIndex, int32 count); + virtual void TableModelReset(TreeTableModel* model); }; @@ -93,6 +94,7 @@ protected: int32 childIndex, int32 count); void NotifyNodesChanged(const TreeTablePath& path, int32 childIndex, int32 count); + void NotifyTableModelReset(); protected: ListenerList fListeners; @@ -217,6 +219,7 @@ private: virtual void TableNodesChanged(TreeTableModel* model, const TreeTablePath& path, int32 childIndex, int32 count); + virtual void TableModelReset(TreeTableModel* model); private: class Column; diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp index 9b2db4333a..92a8cece93 100644 --- a/src/apps/debugger/Debugger.cpp +++ b/src/apps/debugger/Debugger.cpp @@ -100,6 +100,8 @@ struct Options { struct DebuggedProgramInfo { team_id team; thread_id thread; + int commandLineArgc; + const char* const* commandLineArgv; bool stopInMain; }; @@ -266,6 +268,8 @@ get_debugged_program(const Options& options, DebuggedProgramInfo& _info) } printf("team: %" B_PRId32 ", thread: %" B_PRId32 "\n", team, thread); + _info.commandLineArgc = options.commandLineArgc; + _info.commandLineArgv = options.commandLineArgv; _info.team = team; _info.thread = thread; _info.stopInMain = stopInMain; @@ -281,6 +285,7 @@ get_debugged_program(const Options& options, DebuggedProgramInfo& _info) static TeamDebugger* start_team_debugger(team_id teamID, SettingsManager* settingsManager, TeamDebugger::Listener* listener, thread_id threadID = -1, + int commandLineArgc = 0, const char* const* commandLineArgv = NULL, bool stopInMain = false, UserInterface* userInterface = NULL, status_t* _result = NULL) { @@ -303,8 +308,10 @@ start_team_debugger(team_id teamID, SettingsManager* settingsManager, TeamDebugger* debugger = new(std::nothrow) TeamDebugger(listener, userInterface, settingsManager); - if (debugger) - error = debugger->Init(teamID, threadID, stopInMain); + if (debugger) { + error = debugger->Init(teamID, threadID, commandLineArgc, + commandLineArgv, stopInMain); + } if (error != B_OK) { printf("Error: debugger for team %" B_PRId32 " failed to init: %s!\n", @@ -340,6 +347,8 @@ private: private: // TeamDebugger::Listener virtual void TeamDebuggerStarted(TeamDebugger* debugger); + virtual void TeamDebuggerRestartRequested( + TeamDebugger* debugger); virtual void TeamDebuggerQuit(TeamDebugger* debugger); virtual bool QuitRequested(); @@ -371,6 +380,8 @@ public: private: // TeamDebugger::Listener virtual void TeamDebuggerStarted(TeamDebugger* debugger); + virtual void TeamDebuggerRestartRequested( + TeamDebugger* debugger); virtual void TeamDebuggerQuit(TeamDebugger* debugger); }; @@ -455,6 +466,25 @@ Debugger::MessageReceived(BMessage* message) message->SendReply(&reply); break; } + case MSG_TEAM_RESTART_REQUESTED: + { + int32 teamID; + if (message->FindInt32("team", &teamID) != B_OK) + break; + TeamDebugger* debugger = _FindTeamDebugger(teamID); + if (debugger == NULL) + break; + + Options options; + options.commandLineArgc = debugger->ArgumentCount(); + options.commandLineArgv = debugger->Arguments(); + + status_t result = _StartOrFindTeam(options); + if (result == B_OK) + debugger->PostMessage(B_QUIT_REQUESTED); + + break; + } case MSG_TEAM_DEBUGGER_QUIT: { int32 threadID; @@ -528,6 +558,15 @@ Debugger::TeamDebuggerQuit(TeamDebugger* debugger) } +void +Debugger::TeamDebuggerRestartRequested(TeamDebugger* debugger) +{ + BMessage message(MSG_TEAM_RESTART_REQUESTED); + message.AddInt32("team", debugger->TeamID()); + PostMessage(&message); +} + + bool Debugger::QuitRequested() { @@ -574,7 +613,7 @@ Debugger::_StartNewTeam(const char* path, const char* args) return B_BAD_VALUE; BString data; - data.SetToFormat("%s %s", path, args); + data.SetToFormat("\"%s\" %s", path, args); if (data.Length() == 0) return B_NO_MEMORY; @@ -612,7 +651,8 @@ Debugger::_StartOrFindTeam(Options& options) status_t result; start_team_debugger(programInfo.team, &fSettingsManager, this, - programInfo.thread, programInfo.stopInMain, NULL, &result); + programInfo.thread, programInfo.commandLineArgc, + programInfo.commandLineArgv, programInfo.stopInMain, NULL, &result); return result; } @@ -671,8 +711,9 @@ CliDebugger::Run(const Options& options) return false; TeamDebugger* teamDebugger = start_team_debugger(programInfo.team, - &settingsManager, this, programInfo.thread, programInfo.stopInMain, - userInterface); + &settingsManager, this, programInfo.thread, + programInfo.commandLineArgc, programInfo.commandLineArgv, + programInfo.stopInMain, userInterface); if (teamDebugger == NULL) return false; @@ -694,6 +735,13 @@ CliDebugger::TeamDebuggerStarted(TeamDebugger* debugger) } +void +CliDebugger::TeamDebuggerRestartRequested(TeamDebugger* debugger) +{ + // TODO: implement +} + + void CliDebugger::TeamDebuggerQuit(TeamDebugger* debugger) { diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 0f5eab137c..aaf52c569b 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -4,6 +4,10 @@ CCFLAGS += -Werror ; C++FLAGS += -Werror ; UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ; + +# for syscall_numbers.h +UseHeaders [ FDirName $(HAIKU_COMMON_DEBUG_OBJECT_DIR) system kernel ] ; + UsePrivateHeaders app debug interface kernel shared libroot ; UsePrivateSystemHeaders ; @@ -58,6 +62,11 @@ SourceHdrs : [ FDirName $(SUBDIR) dwarf ] ; +# since syscall_numbers.h is generated on the fly, we need to explicitly +# let Jam know about the dependency. +Includes [ FGristFiles TeamDebugger.cpp ] + : syscall_numbers.h ; + Application Debugger : Debugger.cpp @@ -154,6 +163,7 @@ Application Debugger : StackTrace.cpp Statement.cpp SymbolInfo.cpp + SyscallInfo.cpp SystemInfo.cpp Team.cpp TeamInfo.cpp @@ -232,8 +242,10 @@ Application Debugger : TeamsListView.cpp # user_interface/gui/team_window + BreakConditionConfigWindow.cpp BreakpointListView.cpp BreakpointsView.cpp + ConsoleOutputView.cpp ImageFunctionsView.cpp ImageListView.cpp RegistersView.cpp @@ -330,7 +342,7 @@ Application Debugger : libexpression_parser.a libmapm.a libedit.a - libtermcap.a + libncurses.a $(TARGET_LIBSTDC++) be tracker libbsd.so libdebug.so diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index f35929fde1..e0efd00331 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef MESSAGE_CODES_H @@ -8,6 +9,7 @@ enum { MSG_THREAD_RUN = 'run_', + MSG_THREAD_SET_ADDRESS = 'sead', MSG_THREAD_STOP = 'stop', MSG_THREAD_STEP_OVER = 'stov', MSG_THREAD_STEP_INTO = 'stin', @@ -20,12 +22,19 @@ enum { MSG_CLEAR_WATCHPOINT = 'cwpt', MSG_ENABLE_WATCHPOINT = 'ewpt', MSG_DISABLE_WATCHPOINT = 'dwpt', + MSG_STOP_ON_IMAGE_LOAD = 'tsil', + MSG_ADD_STOP_IMAGE_NAME = 'asin', + MSG_REMOVE_STOP_IMAGE_NAME = 'rsin', MSG_THREAD_STATE_CHANGED = 'tsch', MSG_THREAD_CPU_STATE_CHANGED = 'tcsc', MSG_THREAD_STACK_TRACE_CHANGED = 'tstc', MSG_STACK_FRAME_VALUE_RETRIEVED = 'sfvr', MSG_IMAGE_DEBUG_INFO_CHANGED = 'idic', + MSG_STOP_IMAGE_SETTINGS_CHANGED = 'sisc', + MSG_STOP_IMAGE_NAME_ADDED = 'sina', + MSG_STOP_IMAGE_NAME_REMOVED = 'sinr', + MSG_CONSOLE_OUTPUT_RECEIVED = 'core', MSG_IMAGE_FILE_CHANGED = 'ifch', MSG_FUNCTION_SOURCE_CODE_CHANGED = 'fnsc', MSG_USER_BREAKPOINT_CHANGED = 'ubrc', @@ -47,14 +56,18 @@ enum { MSG_VALUE_NODE_VALUE_CHANGED = 'vnvc', MSG_TEAM_DEBUGGER_QUIT = 'dbqt', + MSG_TEAM_RESTART_REQUESTED = 'trrq', MSG_SHOW_TEAMS_WINDOW = 'stsw', MSG_TEAMS_WINDOW_CLOSED = 'tswc', + MSG_SHOW_BREAK_CONDITION_CONFIG_WINDOW = 'sbcc', + MSG_BREAK_CONDITION_CONFIG_WINDOW_CLOSED = 'bccw', MSG_START_NEW_TEAM = 'sttt', MSG_DEBUG_THIS_TEAM = 'dbtt', MSG_SHOW_INSPECTOR_WINDOW = 'sirw', MSG_INSPECTOR_WINDOW_CLOSED = 'irwc', MSG_INSPECT_ADDRESS = 'isad', MSG_SHOW_TYPECAST_NODE_PROMPT = 'stnp', + MSG_TYPECAST_TO_ARRAY = 'stta', MSG_TYPECAST_NODE = 'tyno', MSG_SHOW_WATCH_VARIABLE_PROMPT = 'swvp', MSG_SHOW_CONTAINER_RANGE_PROMPT = 'scrp', diff --git a/src/apps/debugger/arch/CpuState.h b/src/apps/debugger/arch/CpuState.h index 44b845b649..5d50154178 100644 --- a/src/apps/debugger/arch/CpuState.h +++ b/src/apps/debugger/arch/CpuState.h @@ -21,13 +21,22 @@ class CpuState : public BReferenceable { public: virtual ~CpuState(); + virtual status_t Clone(CpuState*& _clone) const = 0; + + virtual status_t UpdateDebugState(void* state, size_t size) + const = 0; + virtual target_addr_t InstructionPointer() const = 0; + virtual void SetInstructionPointer( + target_addr_t address) = 0; + virtual target_addr_t StackFramePointer() const = 0; virtual target_addr_t StackPointer() const = 0; virtual bool GetRegisterValue(const Register* reg, BVariant& _value) const = 0; virtual bool SetRegisterValue(const Register* reg, const BVariant& value) = 0; + }; diff --git a/src/apps/debugger/arch/x86/CpuStateX86.cpp b/src/apps/debugger/arch/x86/CpuStateX86.cpp index 236c5054c3..9ec0e156af 100644 --- a/src/apps/debugger/arch/x86/CpuStateX86.cpp +++ b/src/apps/debugger/arch/x86/CpuStateX86.cpp @@ -1,11 +1,15 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #include "CpuStateX86.h" +#include + +#include + #include "Register.h" @@ -47,6 +51,53 @@ CpuStateX86::~CpuStateX86() } +status_t +CpuStateX86::Clone(CpuState*& _clone) const +{ + CpuStateX86* newState = new(std::nothrow) CpuStateX86(); + if (newState == NULL) + return B_NO_MEMORY; + + + memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters)); + newState->fSetRegisters = fSetRegisters; + newState->fInterruptVector = fInterruptVector; + + _clone = newState; + + return B_OK; +} + + +status_t +CpuStateX86::UpdateDebugState(void* state, size_t size) const +{ + if (size != sizeof(x86_debug_cpu_state)) + return B_BAD_VALUE; + + x86_debug_cpu_state* x86State = (x86_debug_cpu_state*)state; + + x86State->eip = InstructionPointer(); + x86State->user_esp = StackPointer(); + x86State->ebp = StackFramePointer(); + x86State->eax = IntRegisterValue(X86_REGISTER_EAX); + x86State->ebx = IntRegisterValue(X86_REGISTER_EBX); + x86State->ecx = IntRegisterValue(X86_REGISTER_ECX); + x86State->edx = IntRegisterValue(X86_REGISTER_EDX); + x86State->esi = IntRegisterValue(X86_REGISTER_ESI); + x86State->edi = IntRegisterValue(X86_REGISTER_EDI); + x86State->cs = IntRegisterValue(X86_REGISTER_CS); + x86State->ds = IntRegisterValue(X86_REGISTER_DS); + x86State->es = IntRegisterValue(X86_REGISTER_ES); + x86State->fs = IntRegisterValue(X86_REGISTER_FS); + x86State->gs = IntRegisterValue(X86_REGISTER_GS); + x86State->user_ss = IntRegisterValue(X86_REGISTER_SS); + x86State->vector = fInterruptVector; + + return B_OK; +} + + target_addr_t CpuStateX86::InstructionPointer() const { @@ -55,6 +106,13 @@ CpuStateX86::InstructionPointer() const } +void +CpuStateX86::SetInstructionPointer(target_addr_t address) +{ + SetIntRegister(X86_REGISTER_EIP, (uint32)address); +} + + target_addr_t CpuStateX86::StackFramePointer() const { diff --git a/src/apps/debugger/arch/x86/CpuStateX86.h b/src/apps/debugger/arch/x86/CpuStateX86.h index 795d331f82..d32e68c081 100644 --- a/src/apps/debugger/arch/x86/CpuStateX86.h +++ b/src/apps/debugger/arch/x86/CpuStateX86.h @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef CPU_STATE_X86_H @@ -44,7 +44,14 @@ public: CpuStateX86(const x86_debug_cpu_state& state); virtual ~CpuStateX86(); + virtual status_t Clone(CpuState*& _clone) const; + + virtual status_t UpdateDebugState(void* state, size_t size) + const; + virtual target_addr_t InstructionPointer() const; + virtual void SetInstructionPointer(target_addr_t address); + virtual target_addr_t StackFramePointer() const; virtual target_addr_t StackPointer() const; virtual bool GetRegisterValue(const Register* reg, diff --git a/src/apps/debugger/arch/x86_64/CpuStateX8664.cpp b/src/apps/debugger/arch/x86_64/CpuStateX8664.cpp index 1d562e02d0..daa5230010 100644 --- a/src/apps/debugger/arch/x86_64/CpuStateX8664.cpp +++ b/src/apps/debugger/arch/x86_64/CpuStateX8664.cpp @@ -1,12 +1,16 @@ /* * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #include "CpuStateX8664.h" +#include + +#include + #include "Register.h" @@ -52,6 +56,59 @@ CpuStateX8664::~CpuStateX8664() } +status_t +CpuStateX8664::Clone(CpuState*& _clone) const +{ + CpuStateX8664* newState = new(std::nothrow) CpuStateX8664(); + if (newState == NULL) + return B_NO_MEMORY; + + + memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters)); + newState->fSetRegisters = fSetRegisters; + + _clone = newState; + + return B_OK; +} + + +status_t +CpuStateX8664::UpdateDebugState(void* state, size_t size) const +{ + if (size != sizeof(x86_64_debug_cpu_state)) + return B_BAD_VALUE; + + x86_64_debug_cpu_state* x64State = (x86_64_debug_cpu_state*)state; + + x64State->rip = InstructionPointer(); + x64State->rsp = StackPointer(); + x64State->rbp = StackFramePointer(); + x64State->rax = IntRegisterValue(X86_64_REGISTER_RAX); + x64State->rbx = IntRegisterValue(X86_64_REGISTER_RBX); + x64State->rcx = IntRegisterValue(X86_64_REGISTER_RCX); + x64State->rdx = IntRegisterValue(X86_64_REGISTER_RDX); + x64State->rsi = IntRegisterValue(X86_64_REGISTER_RSI); + x64State->rdi = IntRegisterValue(X86_64_REGISTER_RDI); + x64State->r8 = IntRegisterValue(X86_64_REGISTER_R8); + x64State->r9 = IntRegisterValue(X86_64_REGISTER_R9); + x64State->r10 = IntRegisterValue(X86_64_REGISTER_R10); + x64State->r11 = IntRegisterValue(X86_64_REGISTER_R11); + x64State->r12 = IntRegisterValue(X86_64_REGISTER_R12); + x64State->r13 = IntRegisterValue(X86_64_REGISTER_R13); + x64State->r14 = IntRegisterValue(X86_64_REGISTER_R14); + x64State->r15 = IntRegisterValue(X86_64_REGISTER_R15); + x64State->cs = IntRegisterValue(X86_64_REGISTER_CS); + x64State->ds = IntRegisterValue(X86_64_REGISTER_DS); + x64State->es = IntRegisterValue(X86_64_REGISTER_ES); + x64State->fs = IntRegisterValue(X86_64_REGISTER_FS); + x64State->gs = IntRegisterValue(X86_64_REGISTER_GS); + x64State->ss = IntRegisterValue(X86_64_REGISTER_SS); + + return B_OK; +} + + target_addr_t CpuStateX8664::InstructionPointer() const { @@ -60,6 +117,13 @@ CpuStateX8664::InstructionPointer() const } +void +CpuStateX8664::SetInstructionPointer(target_addr_t address) +{ + SetIntRegister(X86_64_REGISTER_RIP, address); +} + + target_addr_t CpuStateX8664::StackFramePointer() const { diff --git a/src/apps/debugger/arch/x86_64/CpuStateX8664.h b/src/apps/debugger/arch/x86_64/CpuStateX8664.h index 2c52d60b90..de3f5b88f9 100644 --- a/src/apps/debugger/arch/x86_64/CpuStateX8664.h +++ b/src/apps/debugger/arch/x86_64/CpuStateX8664.h @@ -1,7 +1,7 @@ /* * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef CPU_STATE_X86_64_H @@ -54,7 +54,14 @@ public: CpuStateX8664(const x86_64_debug_cpu_state& state); virtual ~CpuStateX8664(); + virtual status_t Clone(CpuState*& _clone) const; + + virtual status_t UpdateDebugState(void* state, size_t size) + const; + virtual target_addr_t InstructionPointer() const; + virtual void SetInstructionPointer(target_addr_t address); + virtual target_addr_t StackFramePointer() const; virtual target_addr_t StackPointer() const; virtual bool GetRegisterValue(const Register* reg, diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index fbe38d7eba..b4a391b194 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -14,11 +14,15 @@ #include #include +#include +#include #include #include "debug_utils.h" +#include "syscall_numbers.h" +#include "Architecture.h" #include "BreakpointManager.h" #include "BreakpointSetting.h" #include "CpuState.h" @@ -218,7 +222,9 @@ TeamDebugger::TeamDebugger(Listener* listener, UserInterface* userInterface, fDebugEventListener(-1), fUserInterface(userInterface), fTerminating(false), - fKillTeamOnQuit(false) + fKillTeamOnQuit(false), + fCommandLineArgc(0), + fCommandLineArgv(NULL) { fUserInterface->AcquireReference(); } @@ -293,12 +299,20 @@ TeamDebugger::~TeamDebugger() delete fTeam; delete fFileManager; + for (int i = 0; i < fCommandLineArgc; i++) { + if (fCommandLineArgv[i] != NULL) + free(const_cast(fCommandLineArgv[i])); + } + + delete [] fCommandLineArgv; + fListener->TeamDebuggerQuit(this); } status_t -TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) +TeamDebugger::Init(team_id teamID, thread_id threadID, int argc, + const char* const* argv, bool stopInMain) { bool targetIsLocal = true; // TODO: Support non-local targets! @@ -308,12 +322,16 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) fTeamID = teamID; + status_t error = _HandleSetArguments(argc, argv); + if (error != B_OK) + return error; + // create debugger interface fDebuggerInterface = new(std::nothrow) DebuggerInterface(fTeamID); if (fDebuggerInterface == NULL) return B_NO_MEMORY; - status_t error = fDebuggerInterface->Init(); + error = fDebuggerInterface->Init(); if (error != B_OK) return error; @@ -427,7 +445,8 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) // set team debugging flags fDebuggerInterface->SetTeamDebuggingFlags( - B_TEAM_DEBUG_THREADS | B_TEAM_DEBUG_IMAGES); + B_TEAM_DEBUG_THREADS | B_TEAM_DEBUG_IMAGES + | B_TEAM_DEBUG_POST_SYSCALL); // get the initial state of the team AutoLocker< ::Team> teamLocker(fTeam); @@ -530,17 +549,22 @@ TeamDebugger::MessageReceived(BMessage* message) { switch (message->what) { case MSG_THREAD_RUN: + case MSG_THREAD_SET_ADDRESS: case MSG_THREAD_STOP: case MSG_THREAD_STEP_OVER: case MSG_THREAD_STEP_INTO: case MSG_THREAD_STEP_OUT: { int32 threadID; + target_addr_t address; if (message->FindInt32("thread", &threadID) != B_OK) break; + if (message->FindUInt64("address", &address) != B_OK) + address = 0; + if (ThreadHandler* handler = _GetThreadHandler(threadID)) { - handler->HandleThreadAction(message->what); + handler->HandleThreadAction(message->what, address); handler->ReleaseReference(); } break; @@ -563,10 +587,14 @@ TeamDebugger::MessageReceived(BMessage* message) if (message->FindBool("enabled", &enabled) != B_OK) enabled = true; + bool hidden; + if (message->FindBool("hidden", &hidden) != B_OK) + hidden = false; + if (breakpoint != NULL) _HandleSetUserBreakpoint(breakpoint, enabled); else - _HandleSetUserBreakpoint(address, enabled); + _HandleSetUserBreakpoint(address, enabled, hidden); } else { if (breakpoint != NULL) _HandleClearUserBreakpoint(breakpoint); @@ -577,6 +605,42 @@ TeamDebugger::MessageReceived(BMessage* message) break; } + case MSG_STOP_ON_IMAGE_LOAD: + { + bool enabled; + bool useNames; + if (message->FindBool("enabled", &enabled) != B_OK) + break; + + if (message->FindBool("useNames", &useNames) != B_OK) + break; + + AutoLocker< ::Team> teamLocker(fTeam); + fTeam->SetStopOnImageLoad(enabled, useNames); + break; + } + + case MSG_ADD_STOP_IMAGE_NAME: + { + BString imageName; + if (message->FindString("name", &imageName) != B_OK) + break; + + AutoLocker< ::Team> teamLocker(fTeam); + fTeam->AddStopImageName(imageName); + break; + } + + case MSG_REMOVE_STOP_IMAGE_NAME: + { + BString imageName; + if (message->FindString("name", &imageName) != B_OK) + break; + + AutoLocker< ::Team> teamLocker(fTeam); + fTeam->RemoveStopImageName(imageName); + } + case MSG_SET_WATCHPOINT: case MSG_CLEAR_WATCHPOINT: { @@ -712,6 +776,16 @@ TeamDebugger::MessageReceived(BMessage* message) Activate(); break; + case MSG_TEAM_RESTART_REQUESTED: + { + if (fCommandLineArgc == 0) + break; + + _SaveSettings(); + fListener->TeamDebuggerRestartRequested(this); + break; + } + default: BLooper::MessageReceived(message); break; @@ -729,22 +803,27 @@ TeamDebugger::SourceEntryLocateRequested(const char* sourcePath, void -TeamDebugger::FunctionSourceCodeRequested(FunctionInstance* functionInstance) +TeamDebugger::FunctionSourceCodeRequested(FunctionInstance* functionInstance, + bool forceDisassembly) { Function* function = functionInstance->GetFunction(); // mark loading AutoLocker< ::Team> locker(fTeam); - if (functionInstance->SourceCodeState() != FUNCTION_SOURCE_NOT_LOADED) + if (forceDisassembly && functionInstance->SourceCodeState() + != FUNCTION_SOURCE_NOT_LOADED) { return; - if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) + } else if (!forceDisassembly && function->SourceCodeState() + == FUNCTION_SOURCE_LOADED) { return; + } functionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_LOADING); bool loadForFunction = false; - if (function->SourceCodeState() == FUNCTION_SOURCE_NOT_LOADED) { + if (!forceDisassembly && function->SourceCodeState() + == FUNCTION_SOURCE_NOT_LOADED) { loadForFunction = true; function->SetSourceCode(NULL, FUNCTION_SOURCE_LOADING); } @@ -801,20 +880,23 @@ TeamDebugger::ValueNodeValueRequested(CpuState* cpuState, void TeamDebugger::ThreadActionRequested(thread_id threadID, - uint32 action) + uint32 action, target_addr_t address) { BMessage message(action); message.AddInt32("thread", threadID); + message.AddUInt64("address", address); PostMessage(&message); } void -TeamDebugger::SetBreakpointRequested(target_addr_t address, bool enabled) +TeamDebugger::SetBreakpointRequested(target_addr_t address, bool enabled, + bool hidden) { BMessage message(MSG_SET_BREAKPOINT); message.AddUInt64("address", (uint64)address); message.AddBool("enabled", enabled); + message.AddBool("hidden", hidden); PostMessage(&message); } @@ -842,6 +924,34 @@ TeamDebugger::ClearBreakpointRequested(target_addr_t address) } +void +TeamDebugger::SetStopOnImageLoadRequested(bool enabled, bool useImageNames) +{ + BMessage message(MSG_STOP_ON_IMAGE_LOAD); + message.AddBool("enabled", enabled); + message.AddBool("useNames", useImageNames); + PostMessage(&message); +} + + +void +TeamDebugger::AddStopImageNameRequested(const char* name) +{ + BMessage message(MSG_ADD_STOP_IMAGE_NAME); + message.AddString("name", name); + PostMessage(&message); +} + + +void +TeamDebugger::RemoveStopImageNameRequested(const char* name) +{ + BMessage message(MSG_REMOVE_STOP_IMAGE_NAME); + message.AddString("name", name); + PostMessage(&message); +} + + void TeamDebugger::ClearBreakpointRequested(UserBreakpoint* breakpoint) { @@ -922,6 +1032,13 @@ TeamDebugger::DebugReportRequested(entry_ref* targetPath) } +void +TeamDebugger::TeamRestartRequested() +{ + PostMessage(MSG_TEAM_RESTART_REQUESTED); +} + + bool TeamDebugger::UserInterfaceQuitRequested(QuitOption quitOption) { @@ -1212,8 +1329,28 @@ TeamDebugger::_HandleDebuggerMessage(DebugEvent* event) handled = _HandleImageDeleted(imageEvent); break; } - case B_DEBUGGER_MESSAGE_PRE_SYSCALL: case B_DEBUGGER_MESSAGE_POST_SYSCALL: + { + PostSyscallEvent* postSyscallEvent + = dynamic_cast(event); + TRACE_EVENTS("B_DEBUGGER_MESSAGE_POST_SYSCALL: syscall: %" + B_PRIu32 "\n", postSyscallEvent->GetSyscallInfo().Syscall()); + handled = _HandlePostSyscall(postSyscallEvent); + + // if a thread was blocked in a syscall when we requested to + // stop it for debugging, then that request will interrupt + // said call, and the post syscall event will be all we get + // in response. Consequently, we need to treat this case as + // equivalent to having received a thread debugged event. + AutoLocker< ::Team> teamLocker(fTeam); + ::Thread* thread = fTeam->ThreadByID(event->Thread()); + if (handler != NULL && thread != NULL + && thread->StopRequestPending()) { + handled = handler->HandleThreadDebugged(NULL); + } + break; + } + case B_DEBUGGER_MESSAGE_PRE_SYSCALL: case B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED: case B_DEBUGGER_MESSAGE_PROFILER_UPDATE: case B_DEBUGGER_MESSAGE_HANDED_OVER: @@ -1234,11 +1371,21 @@ bool TeamDebugger::_HandleTeamDeleted(TeamDeletedEvent* event) { char message[64]; - snprintf(message, sizeof(message), "Team %" B_PRId32 " has terminated.", + fDebuggerInterface->Close(false); + + snprintf(message, sizeof(message), "Team %" B_PRId32 " has terminated. ", event->Team()); - fUserInterface->SynchronouslyAskUser("Quit Debugger", message, "Quit", - NULL, NULL); - PostMessage(B_QUIT_REQUESTED); + + int32 result = fUserInterface->SynchronouslyAskUser("Team terminated", + message, "Do nothing", "Quit", fCommandLineArgc != 0 + ? "Restart team" : NULL); + + if (result == 1) + PostMessage(B_QUIT_REQUESTED); + else if (result == 2) { + _SaveSettings(); + fListener->TeamDebuggerRestartRequested(this); + } return true; } @@ -1343,6 +1490,61 @@ TeamDebugger::_HandleImageDeleted(ImageDeletedEvent* event) } +bool +TeamDebugger::_HandlePostSyscall(PostSyscallEvent* event) +{ + const SyscallInfo& info = event->GetSyscallInfo(); + + switch (info.Syscall()) { + case SYSCALL_WRITE: + { + if ((ssize_t)info.ReturnValue() <= 0) + break; + + int32 fd; + target_addr_t address; + size_t size; + // TODO: decoding the syscall arguments should probably be + // factored out into an Architecture method of its own, since + // there's no guarantee the target architecture has the same + // endianness as the host. This could re-use the syscall + // argument parser that strace uses, though that would need to + // be adapted to handle the aforementioned endian differences. + // This works for x86{-64} for now though. + if (fTeam->GetArchitecture()->AddressSize() == 4) { + const uint32* args = (const uint32*)info.Arguments(); + fd = args[0]; + address = args[3]; + size = args[4]; + } else { + const uint64* args = (const uint64*)info.Arguments(); + fd = args[0]; + address = args[2]; + size = args[3]; + } + + if (fd == 1 || fd == 2) { + BString data; + + ssize_t result = fDebuggerInterface->ReadMemoryString( + address, size, data); + if (result >= 0) + fTeam->NotifyConsoleOutputReceived(fd, data); + } + break; + } + case SYSCALL_WRITEV: + { + // TODO: handle + } + default: + break; + } + + return false; +} + + void TeamDebugger::_HandleImageDebugInfoChanged(image_id imageID) { @@ -1366,9 +1568,37 @@ TeamDebugger::_HandleImageDebugInfoChanged(image_id imageID) ImageInfoPendingThread* thread = fImageInfoPendingThreads ->Lookup(imageID); if (thread != NULL) { - fDebuggerInterface->ContinueThread(thread->ThreadID()); fImageInfoPendingThreads->Remove(thread); - delete thread; + ObjectDeleter threadDeleter(thread); + locker.Lock(); + if (fTeam->StopOnImageLoad()) { + ThreadHandler* handler = _GetThreadHandler(thread->ThreadID()); + BReference handlerReference(handler); + + bool stop = true; + const BString& imageName = image->Name(); + // only match on the image filename itself + const char* rawImageName = imageName.String() + + imageName.FindLast('/') + 1; + if (fTeam->StopImageNameListEnabled()) { + const BStringList& nameList = fTeam->StopImageNames(); + stop = nameList.HasString(rawImageName); + } + + if (stop && handler != NULL) { + BString stopReason; + stopReason.SetToFormat("Image '%s' loaded.", + rawImageName); + locker.Unlock(); + + if (handler->HandleThreadDebugged(NULL, stopReason)) + return; + } else + locker.Unlock(); + } else + locker.Unlock(); + + fDebuggerInterface->ContinueThread(thread->ThreadID()); } } } @@ -1384,10 +1614,11 @@ TeamDebugger::_HandleImageFileChanged(image_id imageID) void -TeamDebugger::_HandleSetUserBreakpoint(target_addr_t address, bool enabled) +TeamDebugger::_HandleSetUserBreakpoint(target_addr_t address, bool enabled, + bool hidden) { TRACE_CONTROL("TeamDebugger::_HandleSetUserBreakpoint(%#" B_PRIx64 - ", %d)\n", address, enabled); + ", %d, %d)\n", address, enabled, hidden); // check whether there already is a breakpoint AutoLocker< ::Team> locker(fTeam); @@ -1459,6 +1690,8 @@ TeamDebugger::_HandleSetUserBreakpoint(target_addr_t address, bool enabled) return; userBreakpointReference.SetTo(userBreakpoint, true); + userBreakpoint->SetHidden(hidden); + TRACE_CONTROL(" created user breakpoint: %p\n", userBreakpoint); // iterate through all function instances and create @@ -1629,12 +1862,12 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address, return; } - if (!memoryBlock->HasListener(listener)) - memoryBlock->AddListener(listener); - if (!memoryBlock->IsValid()) { AutoLocker< ::Team> teamLocker(fTeam); + if (!memoryBlock->HasListener(listener)) + memoryBlock->AddListener(listener); + TeamMemory* memory = fTeam->GetTeamMemory(); // schedule the job status_t result; @@ -1642,7 +1875,10 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address, new(std::nothrow) RetrieveMemoryBlockJob(fTeam, memory, memoryBlock), this)) != B_OK) { + + memoryBlock->NotifyDataRetrieved(result); memoryBlock->ReleaseReference(); + _NotifyUser("Inspect Address", "Failed to retrieve memory data: %s", strerror(result)); } @@ -1652,6 +1888,26 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address, } +status_t +TeamDebugger::_HandleSetArguments(int argc, const char* const* argv) +{ + fCommandLineArgc = argc; + fCommandLineArgv = new(std::nothrow) const char*[argc]; + if (fCommandLineArgv == NULL) + return B_NO_MEMORY; + + memset(const_cast(fCommandLineArgv), 0, sizeof(char*) * argc); + + for (int i = 0; i < argc; i++) { + fCommandLineArgv[i] = strdup(argv[i]); + if (fCommandLineArgv[i] == NULL) + return B_NO_MEMORY; + } + + return B_OK; +} + + ThreadHandler* TeamDebugger::_GetThreadHandler(thread_id threadID) { @@ -1728,6 +1984,8 @@ TeamDebugger::_LoadSettings() return; BReference breakpointReference(breakpoint, true); + breakpoint->SetHidden(breakpointSetting->IsHidden()); + // install it fBreakpointManager->InstallUserBreakpoint(breakpoint, breakpointSetting->IsEnabled()); diff --git a/src/apps/debugger/controllers/TeamDebugger.h b/src/apps/debugger/controllers/TeamDebugger.h index 700c01a430..c91fc583da 100644 --- a/src/apps/debugger/controllers/TeamDebugger.h +++ b/src/apps/debugger/controllers/TeamDebugger.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_DEBUGGER_H @@ -40,18 +41,26 @@ public: ~TeamDebugger(); status_t Init(team_id teamID, thread_id threadID, + int argc, + const char* const* argv, bool stopInMain); void Activate(); team_id TeamID() const { return fTeamID; } + int ArgumentCount() const + { return fCommandLineArgc; } + const char** Arguments() const + { return fCommandLineArgv; } + virtual void MessageReceived(BMessage* message); private: // UserInterfaceListener virtual void FunctionSourceCodeRequested( - FunctionInstance* function); + FunctionInstance* function, + bool forceDisassembly = false); virtual void SourceEntryLocateRequested( const char* sourcePath, const char* locatedPath); @@ -60,15 +69,24 @@ private: ValueNodeContainer* container, ValueNode* valueNode); virtual void ThreadActionRequested(thread_id threadID, - uint32 action); + uint32 action, target_addr_t address); + virtual void SetBreakpointRequested(target_addr_t address, - bool enabled); + bool enabled, bool hidden = false); virtual void SetBreakpointEnabledRequested( UserBreakpoint* breakpoint, bool enabled); virtual void ClearBreakpointRequested(target_addr_t address); virtual void ClearBreakpointRequested( UserBreakpoint* breakpoint); + + virtual void SetStopOnImageLoadRequested(bool enabled, + bool useImageNames); + virtual void AddStopImageNameRequested( + const char* name); + virtual void RemoveStopImageNameRequested( + const char* name); + virtual void SetWatchpointRequested(target_addr_t address, uint32 type, int32 length, bool enabled); virtual void SetWatchpointEnabledRequested( @@ -82,6 +100,8 @@ private: virtual void DebugReportRequested(entry_ref* targetPath); + virtual void TeamRestartRequested(); + virtual bool UserInterfaceQuitRequested( QuitOption quitOption); @@ -130,12 +150,14 @@ private: ImageCreatedEvent* event); bool _HandleImageDeleted( ImageDeletedEvent* event); + bool _HandlePostSyscall( + PostSyscallEvent* event); void _HandleImageDebugInfoChanged(image_id imageID); void _HandleImageFileChanged(image_id imageID); void _HandleSetUserBreakpoint(target_addr_t address, - bool enabled); + bool enabled, bool hidden); void _HandleSetUserBreakpoint( UserBreakpoint* breakpoint, bool enabled); void _HandleClearUserBreakpoint( @@ -153,6 +175,8 @@ private: void _HandleInspectAddress( target_addr_t address, TeamMemoryBlock::Listener* listener); + status_t _HandleSetArguments(int argc, + const char* const* argv); ThreadHandler* _GetThreadHandler(thread_id threadID); @@ -189,6 +213,8 @@ private: volatile bool fTerminating; bool fKillTeamOnQuit; TeamSettings fTeamSettings; + int fCommandLineArgc; + const char** fCommandLineArgv; }; @@ -197,6 +223,8 @@ public: virtual ~Listener(); virtual void TeamDebuggerStarted(TeamDebugger* debugger) = 0; + virtual void TeamDebuggerRestartRequested( + TeamDebugger* debugger) = 0; virtual void TeamDebuggerQuit(TeamDebugger* debugger) = 0; }; diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp b/src/apps/debugger/controllers/ThreadHandler.cpp index 5b79d148a5..3a1a02f289 100644 --- a/src/apps/debugger/controllers/ThreadHandler.cpp +++ b/src/apps/debugger/controllers/ThreadHandler.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010-2011, Rene Gollent, rene@gollent.com. + * Copyright 2010-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -37,7 +37,8 @@ enum { STEP_NONE, STEP_OVER, STEP_INTO, - STEP_OUT + STEP_OUT, + STEP_UNTIL }; @@ -97,9 +98,10 @@ ThreadHandler::SetBreakpointAndRun(target_addr_t address) bool -ThreadHandler::HandleThreadDebugged(ThreadDebuggedEvent* event) +ThreadHandler::HandleThreadDebugged(ThreadDebuggedEvent* event, + const BString& stoppedReason) { - return _HandleThreadStopped(NULL, THREAD_STOPPED_DEBUGGED); + return _HandleThreadStopped(NULL, THREAD_STOPPED_DEBUGGED, stoppedReason); } @@ -124,7 +126,7 @@ ThreadHandler::HandleBreakpointHit(BreakpointHitEvent* event) // check whether this is a temporary breakpoint we're waiting for if (fBreakpointAddress != 0 && instructionPointer == fBreakpointAddress && fStepMode != STEP_NONE) { - if (_HandleBreakpointHitStep(cpuState)) + if (fStepMode != STEP_UNTIL && _HandleBreakpointHitStep(cpuState)) return true; } else { // Might be a user breakpoint, but could as well be a temporary @@ -199,7 +201,7 @@ ThreadHandler::HandleExceptionOccurred(ExceptionOccurredEvent* event) void -ThreadHandler::HandleThreadAction(uint32 action) +ThreadHandler::HandleThreadAction(uint32 action, target_addr_t address) { AutoLocker locker(fThread->GetTeam()); @@ -219,6 +221,11 @@ ThreadHandler::HandleThreadAction(uint32 action) BReference cpuStateReference(cpuState); BReference stackTraceReference(stackTrace); + if (action == MSG_THREAD_SET_ADDRESS) { + _HandleSetAddress(cpuState, address); + return; + } + // When continuing the thread update thread state before actually issuing // the command, since we need to unlock. if (action != MSG_THREAD_STOP) { @@ -230,12 +237,15 @@ ThreadHandler::HandleThreadAction(uint32 action) switch (action) { case MSG_THREAD_RUN: - fStepMode = STEP_NONE; + fStepMode = address != 0 ? STEP_UNTIL : STEP_NONE; + if (address != 0) + _InstallTemporaryBreakpoint(address); _RunThread(0); return; case MSG_THREAD_STOP: fStepMode = STEP_NONE; - fDebuggerInterface->StopThread(ThreadID()); + if (fDebuggerInterface->StopThread(ThreadID()) == B_OK) + fThread->SetStopRequestPending(); return; case MSG_THREAD_STEP_OVER: case MSG_THREAD_STEP_INTO: @@ -409,6 +419,26 @@ ThreadHandler::_HandleThreadStopped(CpuState* cpuState, uint32 stoppedReason, } +bool +ThreadHandler::_HandleSetAddress(CpuState* state, target_addr_t address) +{ + CpuState* newState = NULL; + if (state->Clone(newState) != B_OK) + return false; + BReference stateReference(newState, true); + + newState->SetInstructionPointer(address); + if (fDebuggerInterface->SetCpuState(fThread->ID(), newState) != B_OK) + return false; + + AutoLocker locker(fThread->GetTeam()); + fThread->SetStackTrace(NULL); + fThread->SetCpuState(newState); + + return true; +} + + void ThreadHandler::_SetThreadState(uint32 state, CpuState* cpuState, uint32 stoppedReason, const BString& stoppedReasonInfo) diff --git a/src/apps/debugger/controllers/ThreadHandler.h b/src/apps/debugger/controllers/ThreadHandler.h index 4fd078565a..3bbff417bb 100644 --- a/src/apps/debugger/controllers/ThreadHandler.h +++ b/src/apps/debugger/controllers/ThreadHandler.h @@ -41,7 +41,8 @@ public: // All Handle*() methods are invoked in team debugger thread, // looper lock held. bool HandleThreadDebugged( - ThreadDebuggedEvent* event); + ThreadDebuggedEvent* event, + const BString& stoppedReason = BString()); bool HandleDebuggerCall( DebuggerCallEvent* event); bool HandleBreakpointHit( @@ -53,7 +54,8 @@ public: bool HandleExceptionOccurred( ExceptionOccurredEvent* event); - void HandleThreadAction(uint32 action); + void HandleThreadAction(uint32 action, + target_addr_t address); void HandleThreadStateChanged(); void HandleCpuStateChanged(); @@ -69,6 +71,9 @@ private: const BString& stoppedReasonInfo = BString()); + bool _HandleSetAddress(CpuState* cpuState, + target_addr_t address); + void _SetThreadState(uint32 state, CpuState* cpuState, uint32 stoppedReason, const BString& stoppedReasonInfo); diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index 254fd36ce0..58e478ace2 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -705,7 +705,8 @@ DwarfImageDebugInfo::GetStatement(FunctionDebugInfo* _function, = dynamic_cast(_function); if (function == NULL) { TRACE_LINES(" -> no dwarf function\n"); - return B_BAD_VALUE; + // fall back to assembly + return fArchitecture->GetStatement(function, address, _statement); } AutoLocker locker(fLock); diff --git a/src/apps/debugger/debug_info/DwarfTypeFactory.cpp b/src/apps/debugger/debug_info/DwarfTypeFactory.cpp index ed28f8820c..032c129f5c 100644 --- a/src/apps/debugger/debug_info/DwarfTypeFactory.cpp +++ b/src/apps/debugger/debug_info/DwarfTypeFactory.cpp @@ -301,7 +301,6 @@ DwarfTypeFactory::CreateType(DIEType* typeEntry, DwarfType*& _type) // try the type cache first BString name; DwarfUtils::GetFullyQualifiedDIEName(typeEntry, name); -// TODO: The DIE may not have a name (e.g. pointer and reference types don't). TypeLookupConstraints constraints( dwarf_tag_to_type_kind(typeEntry->Tag())); diff --git a/src/apps/debugger/debug_info/TeamDebugInfo.cpp b/src/apps/debugger/debug_info/TeamDebugInfo.cpp index d44158587e..802f4a7094 100644 --- a/src/apps/debugger/debug_info/TeamDebugInfo.cpp +++ b/src/apps/debugger/debug_info/TeamDebugInfo.cpp @@ -431,7 +431,7 @@ TeamDebugInfo::LoadImageDebugInfo(const ImageInfo& imageInfo, imageInfo); if (imageDebugInfo == NULL) return B_NO_MEMORY; - ObjectDeleter imageDebugInfoDeleter(imageDebugInfo); + BReference imageDebugInfoReference(imageDebugInfo, true); for (int32 i = 0; SpecificTeamDebugInfo* specificTeamInfo = fSpecificInfos.ItemAt(i); i++) { @@ -452,7 +452,7 @@ TeamDebugInfo::LoadImageDebugInfo(const ImageInfo& imageInfo, if (error != B_OK) return error; - _imageDebugInfo = imageDebugInfoDeleter.Detach(); + _imageDebugInfo = imageDebugInfoReference.Detach(); return B_OK; } diff --git a/src/apps/debugger/debug_managers/BreakpointManager.cpp b/src/apps/debugger/debug_managers/BreakpointManager.cpp index 998f9fcd04..71dd193281 100644 --- a/src/apps/debugger/debug_managers/BreakpointManager.cpp +++ b/src/apps/debugger/debug_managers/BreakpointManager.cpp @@ -494,8 +494,13 @@ BreakpointManager::_UpdateBreakpointInstallation(Breakpoint* breakpoint) if (shouldBeInstalled) { // install - status_t error = fDebuggerInterface->InstallBreakpoint( - breakpoint->Address()); + status_t error = B_OK; + // if we're not actually connected to a team, silently + // allow setting the breakpoint so it's saved to settings + // for when we do connect/have the team in the debugger. + if (fDebuggerInterface->Connected()) + fDebuggerInterface->InstallBreakpoint(breakpoint->Address()); + if (error != B_OK) return error; diff --git a/src/apps/debugger/debugger_interface/DebugEvent.cpp b/src/apps/debugger/debugger_interface/DebugEvent.cpp index c3bf1276a8..16dac7328a 100644 --- a/src/apps/debugger/debugger_interface/DebugEvent.cpp +++ b/src/apps/debugger/debugger_interface/DebugEvent.cpp @@ -215,6 +215,18 @@ ImageDeletedEvent::ImageDeletedEvent(team_id team, thread_id thread, } +// #pragma mark - PostSyscallEvent + + +PostSyscallEvent::PostSyscallEvent(team_id team, thread_id thread, + const SyscallInfo& info) + : + DebugEvent(B_DEBUGGER_MESSAGE_POST_SYSCALL, team, thread), + fInfo(info) +{ +} + + // #pragma mark - HandedOverEvent diff --git a/src/apps/debugger/debugger_interface/DebugEvent.h b/src/apps/debugger/debugger_interface/DebugEvent.h index dda16cb1dd..edd81400df 100644 --- a/src/apps/debugger/debugger_interface/DebugEvent.h +++ b/src/apps/debugger/debugger_interface/DebugEvent.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DEBUG_EVENT_H @@ -8,6 +9,7 @@ #include #include "ImageInfo.h" +#include "SyscallInfo.h" #include "Types.h" @@ -196,6 +198,19 @@ private: }; +class PostSyscallEvent : public DebugEvent { +public: + PostSyscallEvent(team_id team, + thread_id thread, + const SyscallInfo& info); + + const SyscallInfo& GetSyscallInfo() const { return fInfo; } + +private: + SyscallInfo fInfo; +}; + + class HandedOverEvent : public DebugEvent { public: HandedOverEvent(team_id team, diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp index 4edcd9a6fc..9d413a4fbc 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp @@ -23,6 +23,7 @@ #include "ArchitectureX86.h" #include "ArchitectureX8664.h" #include "AreaInfo.h" +#include "AutoDeleter.h" #include "CpuState.h" #include "DebugEvent.h" #include "ImageInfo.h" @@ -315,6 +316,9 @@ DebuggerInterface::Close(bool killTeam) if (fDebuggerPort >= 0) delete_port(fDebuggerPort); + + fNubPort = -1; + fDebuggerPort = -1; } @@ -347,8 +351,10 @@ DebuggerInterface::GetNextDebugEvent(DebugEvent*& _event) if (ignore) { if (message.origin.thread >= 0 && message.origin.nub_port >= 0) - continue_thread(message.origin.nub_port, + error = continue_thread(message.origin.nub_port, message.origin.thread); + if (error != B_OK) + return error; continue; } @@ -369,16 +375,14 @@ DebuggerInterface::GetNextDebugEvent(DebugEvent*& _event) status_t DebuggerInterface::SetTeamDebuggingFlags(uint32 flags) { - set_team_debugging_flags(fNubPort, flags); - return B_OK; + return set_team_debugging_flags(fNubPort, flags); } status_t DebuggerInterface::ContinueThread(thread_id thread) { - continue_thread(fNubPort, thread); - return B_OK; + return continue_thread(fNubPort, thread); } @@ -663,24 +667,37 @@ DebuggerInterface::GetThreadInfo(thread_id thread, ThreadInfo& info) status_t DebuggerInterface::GetCpuState(thread_id thread, CpuState*& _state) { - DebugContextGetter contextGetter(fDebugContextPool); - - debug_nub_get_cpu_state message; - message.reply_port = contextGetter.Context()->reply_port; - message.thread = thread; - - debug_nub_get_cpu_state_reply reply; - - status_t error = send_debug_message(contextGetter.Context(), - B_DEBUG_MESSAGE_GET_CPU_STATE, &message, sizeof(message), &reply, - sizeof(reply)); + debug_cpu_state debugState; + status_t error = _GetDebugCpuState(thread, debugState); if (error != B_OK) return error; - if (reply.error != B_OK) - return reply.error; + return fArchitecture->CreateCpuState(&debugState, sizeof(debug_cpu_state), + _state); +} - return fArchitecture->CreateCpuState(&reply.cpu_state, - sizeof(debug_cpu_state), _state); + +status_t +DebuggerInterface::SetCpuState(thread_id thread, const CpuState* state) +{ + debug_cpu_state debugState; + status_t error = _GetDebugCpuState(thread, debugState); + if (error != B_OK) + return error; + + DebugContextGetter contextGetter(fDebugContextPool); + + error = state->UpdateDebugState(&debugState, sizeof(debugState)); + if (error != B_OK) + return error; + + debug_nub_set_cpu_state message; + message.thread = thread; + + memcpy(&message.cpu_state, &debugState, sizeof(debugState)); + + return send_debug_message(contextGetter.Context(), + B_DEBUG_MESSAGE_SET_CPU_STATE, &message, sizeof(message), NULL, + 0); } @@ -813,13 +830,22 @@ DebuggerInterface::_CreateDebugEvent(int32 messageCode, info.data_size)); break; } + case B_DEBUGGER_MESSAGE_POST_SYSCALL: + { + event = new(std::nothrow) PostSyscallEvent(message.origin.team, + message.origin.thread, + SyscallInfo(message.post_syscall.start_time, + message.post_syscall.end_time, + message.post_syscall.return_value, + message.post_syscall.syscall, message.post_syscall.args)); + break; + } default: printf("DebuggerInterface for team %" B_PRId32 ": unknown message " "from kernel: %" B_PRId32 "\n", fTeamID, messageCode); // fall through... case B_DEBUGGER_MESSAGE_TEAM_CREATED: case B_DEBUGGER_MESSAGE_PRE_SYSCALL: - case B_DEBUGGER_MESSAGE_POST_SYSCALL: case B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED: case B_DEBUGGER_MESSAGE_PROFILER_UPDATE: case B_DEBUGGER_MESSAGE_HANDED_OVER: @@ -883,3 +909,28 @@ DebuggerInterface::_GetNextSystemWatchEvent(DebugEvent*& _event, return error; } + + +status_t +DebuggerInterface::_GetDebugCpuState(thread_id thread, debug_cpu_state& _state) +{ + DebugContextGetter contextGetter(fDebugContextPool); + + debug_nub_get_cpu_state message; + message.reply_port = contextGetter.Context()->reply_port; + message.thread = thread; + + debug_nub_get_cpu_state_reply reply; + + status_t error = send_debug_message(contextGetter.Context(), + B_DEBUG_MESSAGE_GET_CPU_STATE, &message, sizeof(message), &reply, + sizeof(reply)); + if (error != B_OK) + return error; + if (reply.error != B_OK) + return reply.error; + + memcpy(&_state, &reply.cpu_state, sizeof(debug_cpu_state)); + + return B_OK; +} diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.h b/src/apps/debugger/debugger_interface/DebuggerInterface.h index 39d655c818..def878efff 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.h +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.h @@ -38,6 +38,9 @@ public: status_t Init(); void Close(bool killTeam); + bool Connected() const + { return fNubPort >= 0; } + Architecture* GetArchitecture() const { return fArchitecture; } @@ -74,6 +77,8 @@ public: virtual status_t GetCpuState(thread_id thread, CpuState*& _state); // returns a reference to the caller + virtual status_t SetCpuState(thread_id thread, + const CpuState* state); // TeamMemory virtual ssize_t ReadMemory(target_addr_t address, void* buffer, @@ -94,6 +99,9 @@ private: status_t _GetNextSystemWatchEvent(DebugEvent*& _event, BPrivate::KMessage& message); + status_t _GetDebugCpuState(thread_id thread, + debug_cpu_state& _state); + private: team_id fTeamID; port_id fDebuggerPort; diff --git a/src/apps/debugger/dwarf/AttributeClasses.cpp b/src/apps/debugger/dwarf/AttributeClasses.cpp index 438bfdabc8..89e5b8b6eb 100644 --- a/src/apps/debugger/dwarf/AttributeClasses.cpp +++ b/src/apps/debugger/dwarf/AttributeClasses.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -17,7 +18,8 @@ enum { AC_MACPTR = 1 << (ATTRIBUTE_CLASS_MACPTR - 1), AC_RANGELISTPTR = 1 << (ATTRIBUTE_CLASS_RANGELISTPTR - 1), AC_REFERENCE = 1 << (ATTRIBUTE_CLASS_REFERENCE - 1), - AC_STRING = 1 << (ATTRIBUTE_CLASS_STRING - 1) + AC_STRING = 1 << (ATTRIBUTE_CLASS_STRING - 1), + AC_EXPRESSION = 1 << (ATTRIBUTE_CLASS_EXPRESSION - 1) }; @@ -127,10 +129,26 @@ static const attribute_name_info_entry kAttributeNameInfos[] = { { ENTRY(elemental), AC_FLAG }, { ENTRY(pure), AC_FLAG }, { ENTRY(recursive), AC_FLAG }, + { ENTRY(signature), AC_REFERENCE }, + { ENTRY(main_subprogram), AC_FLAG }, + { ENTRY(data_bit_offset), AC_CONSTANT }, + { ENTRY(const_expr), AC_FLAG }, + { ENTRY(enum_class), AC_FLAG }, + { ENTRY(linkage_name), AC_STRING }, + { ENTRY(call_site_value), AC_BLOCK | AC_EXPRESSION }, + { ENTRY(call_site_data_value), AC_BLOCK | AC_EXPRESSION }, + { ENTRY(call_site_target), AC_BLOCK | AC_EXPRESSION }, + { ENTRY(call_site_target_clobbered), + AC_BLOCK | AC_EXPRESSION }, + { ENTRY(tail_call), AC_FLAG }, + { ENTRY(all_tail_call_sites), AC_FLAG }, + { ENTRY(all_call_sites), AC_FLAG }, + { ENTRY(all_source_call_sites), AC_FLAG }, + {} }; -static const uint32 kAttributeNameInfoCount = DW_AT_recursive + 1; +static const uint32 kAttributeNameInfoCount = DW_AT_linkage_name + 9; static attribute_name_info_entry sAttributeNameInfos[kAttributeNameInfoCount]; @@ -160,10 +178,16 @@ static const attribute_info_entry kAttributeFormInfos[] = { { ENTRY(ref4), AC_REFERENCE }, { ENTRY(ref8), AC_REFERENCE }, { ENTRY(ref_udata), AC_REFERENCE }, + { ENTRY(indirect), AC_REFERENCE }, + { ENTRY(sec_offset), AC_LINEPTR | AC_LOCLISTPTR | AC_MACPTR + | AC_RANGELISTPTR }, + { ENTRY(exprloc), AC_EXPRESSION }, + { ENTRY(flag_present), AC_FLAG }, + { ENTRY(ref_sig8), AC_REFERENCE }, {} }; -static const uint32 kAttributeFormInfoCount = DW_FORM_ref_udata + 1; +static const uint32 kAttributeFormInfoCount = DW_FORM_ref_sig8 + 1; static attribute_info_entry sAttributeFormInfos[kAttributeFormInfoCount]; static struct InitAttributeInfos { @@ -171,7 +195,12 @@ static struct InitAttributeInfos { { for (uint32 i = 0; kAttributeNameInfos[i].name != NULL; i++) { const attribute_name_info_entry& entry = kAttributeNameInfos[i]; - sAttributeNameInfos[entry.value] = entry; + if (entry.value <= DW_AT_linkage_name) + sAttributeNameInfos[entry.value] = entry; + else { + sAttributeNameInfos[DW_AT_linkage_name + 1 + + (entry.value - DW_AT_call_site_value)] = entry; + } } for (uint32 i = 0; kAttributeFormInfos[i].name != NULL; i++) { @@ -185,8 +214,15 @@ static struct InitAttributeInfos { uint16 get_attribute_name_classes(uint32 name) { - return name < kAttributeNameInfoCount - ? sAttributeNameInfos[name].classes : 0; + if (name < DW_AT_linkage_name) + return sAttributeNameInfos[name].classes; + else if (name >= DW_AT_call_site_value + && name <= DW_AT_all_source_call_sites) { + return sAttributeNameInfos[DW_AT_linkage_name + 1 + + (name - DW_AT_call_site_value)].classes; + } + + return 0; } @@ -217,8 +253,15 @@ get_attribute_class(uint32 name, uint32 form) const char* get_attribute_name_name(uint32 name) { - return name < kAttributeNameInfoCount - ? sAttributeNameInfos[name].name : NULL; + if (name < DW_AT_linkage_name) + return sAttributeNameInfos[name].name; + else if (name >= DW_AT_call_site_value + && name <= DW_AT_all_source_call_sites) { + return sAttributeNameInfos[DW_AT_linkage_name + 1 + + (name - DW_AT_call_site_value)].name; + } + + return NULL; } diff --git a/src/apps/debugger/dwarf/AttributeClasses.h b/src/apps/debugger/dwarf/AttributeClasses.h index ae9424fd65..6b7b873f3d 100644 --- a/src/apps/debugger/dwarf/AttributeClasses.h +++ b/src/apps/debugger/dwarf/AttributeClasses.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef ATTRIBUTE_TABLES_H @@ -24,7 +25,8 @@ enum { ATTRIBUTE_CLASS_MACPTR = 7, ATTRIBUTE_CLASS_RANGELISTPTR = 8, ATTRIBUTE_CLASS_REFERENCE = 9, - ATTRIBUTE_CLASS_STRING = 10 + ATTRIBUTE_CLASS_STRING = 10, + ATTRIBUTE_CLASS_EXPRESSION = 11 }; diff --git a/src/apps/debugger/dwarf/DebugInfoEntries.cpp b/src/apps/debugger/dwarf/DebugInfoEntries.cpp index be38f23a2c..9d3ff63f31 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntries.cpp +++ b/src/apps/debugger/dwarf/DebugInfoEntries.cpp @@ -1840,6 +1840,7 @@ DIESubprogram::DIESubprogram() fAddressClass(0), fPrototyped(false), fInline(DW_INL_not_inlined), + fMain(false), fArtificial(false), fCallingConvention(DW_CC_normal) { @@ -1893,6 +1894,9 @@ DIESubprogram::AddChild(DebugInfoEntry* child) case DW_TAG_template_value_parameter: fTemplateValueParameters.Add(child); return B_OK; + case DW_TAG_GNU_call_site: + fCallSites.Add(child); + return B_OK; default: return DIEDeclaredNamedBase::AddChild(child); } @@ -2018,6 +2022,15 @@ DIESubprogram::AddAttribute_calling_convention(uint16 attributeName, } +status_t +DIESubprogram::AddAttribute_main_subprogram(uint16 attributeName, + const AttributeValue& value) +{ + fMain = true; + return B_OK; +} + + // #pragma mark - DIETemplateTypeParameter @@ -2604,6 +2617,91 @@ DIETemplateValueParameterPack::AddChild(DebugInfoEntry* child) } +// #pragma mark - DIECallSite + + +DIECallSite::DIECallSite() + : + fName(NULL) +{ +} + + +uint16 +DIECallSite::Tag() const +{ + return DW_TAG_GNU_call_site; +} + + +const char* +DIECallSite::Name() const +{ + return fName; +} + + +status_t +DIECallSite::AddAttribute_name(uint16 attributeName, + const AttributeValue& value) +{ + fName = value.string; + return B_OK; +} + + +status_t +DIECallSite::AddChild(DebugInfoEntry* child) +{ + if (child->Tag() == DW_TAG_GNU_call_site_parameter) { + fChildren.Add(child); + return B_OK; + } + + return DIEDeclaredBase::AddChild(child); +} + + +// #pragma mark - DIECallSiteParameter + + +DIECallSiteParameter::DIECallSiteParameter() + : + fName(NULL) +{ +} + + +uint16 +DIECallSiteParameter::Tag() const +{ + return DW_TAG_GNU_call_site_parameter; +} + + +const char* +DIECallSiteParameter::Name() const +{ + return fName; +} + + +status_t +DIECallSiteParameter::AddAttribute_name(uint16 attributeName, + const AttributeValue& value) +{ + fName = value.string; + return B_OK; +} + + +status_t +DIECallSiteParameter::AddChild(DebugInfoEntry* child) +{ + return DIEDeclaredBase::AddChild(child); +} + + // #pragma mark - DebugInfoEntryFactory @@ -2795,6 +2893,12 @@ DebugInfoEntryFactory::CreateDebugInfoEntry(uint16 tag, DebugInfoEntry*& _entry) case DW_TAG_GNU_formal_parameter_pack: entry = new(std::nothrow) DIETemplateValueParameterPack; break; + case DW_TAG_GNU_call_site: + entry = new(std::nothrow) DIECallSite; + break; + case DW_TAG_GNU_call_site_parameter: + entry = new(std::nothrow) DIECallSiteParameter; + break; default: return B_ENTRY_NOT_FOUND; break; diff --git a/src/apps/debugger/dwarf/DebugInfoEntries.h b/src/apps/debugger/dwarf/DebugInfoEntries.h index a4a5c01ce4..0c74f68b3c 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntries.h +++ b/src/apps/debugger/dwarf/DebugInfoEntries.h @@ -1225,12 +1225,15 @@ public: { return fTemplateTypeParameters; } const DebugInfoEntryList TemplateValueParameters() const { return fTemplateValueParameters; } + const DebugInfoEntryList CallSites() const + { return fCallSites; } bool IsPrototyped() const { return fPrototyped; } uint8 Inline() const { return fInline; } bool IsArtificial() const { return fArtificial; } uint8 CallingConvention() const { return fCallingConvention; } + bool IsMain() const { return fMain; } DIEType* ReturnType() const { return fReturnType; } @@ -1264,6 +1267,10 @@ public: virtual status_t AddAttribute_calling_convention( uint16 attributeName, const AttributeValue& value); + virtual status_t AddAttribute_main_subprogram( + uint16 attributeName, + const AttributeValue& value); + protected: DebugInfoEntryList fParameters; @@ -1271,6 +1278,7 @@ protected: DebugInfoEntryList fBlocks; DebugInfoEntryList fTemplateTypeParameters; DebugInfoEntryList fTemplateValueParameters; + DebugInfoEntryList fCallSites; target_addr_t fLowPC; target_addr_t fHighPC; off_t fAddressRangesOffset; @@ -1281,6 +1289,7 @@ protected: uint8 fAddressClass; bool fPrototyped; uint8 fInline; + bool fMain; bool fArtificial; uint8 fCallingConvention; @@ -1641,6 +1650,50 @@ private: }; +class DIECallSite : public DIEDeclaredBase { +public: + DIECallSite(); + + virtual uint16 Tag() const; + + virtual const char* Name() const; + + virtual status_t AddAttribute_name(uint16 attributeName, + const AttributeValue& value); + + const DebugInfoEntryList& Children() const + { return fChildren; } + + virtual status_t AddChild(DebugInfoEntry* child); + +private: + const char* fName; + DebugInfoEntryList fChildren; +}; + + +class DIECallSiteParameter : public DIEDeclaredBase { +public: + DIECallSiteParameter(); + + virtual uint16 Tag() const; + + virtual const char* Name() const; + + virtual status_t AddAttribute_name(uint16 attributeName, + const AttributeValue& value); + + const DebugInfoEntryList& Children() const + { return fChildren; } + + virtual status_t AddChild(DebugInfoEntry* child); + +private: + const char* fName; + DebugInfoEntryList fChildren; +}; + + // #pragma mark - DebugInfoEntryFactory diff --git a/src/apps/debugger/dwarf/DebugInfoEntry.cpp b/src/apps/debugger/dwarf/DebugInfoEntry.cpp index 534636ea22..4938e8ab67 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntry.cpp +++ b/src/apps/debugger/dwarf/DebugInfoEntry.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -299,6 +300,20 @@ DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(endianity) DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(elemental) DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(pure) DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(recursive) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(signature) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(main_subprogram) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(data_bit_offset) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(const_expr) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(enum_class) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(linkage_name) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_value) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_data_value) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target_clobbered) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(tail_call) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_tail_call_sites) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_call_sites) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_source_call_sites) DeclarationLocation* diff --git a/src/apps/debugger/dwarf/DebugInfoEntry.h b/src/apps/debugger/dwarf/DebugInfoEntry.h index 6cd54c04e9..11e7865035 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntry.h +++ b/src/apps/debugger/dwarf/DebugInfoEntry.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DEBUG_INFO_ENTRY_H @@ -162,6 +163,20 @@ public: DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(elemental) DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(pure) DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(recursive) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(signature) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(main_subprogram) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(data_bit_offset) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(const_expr) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(enum_class) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(linkage_name) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_value) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_data_value) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target_clobbered) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(tail_call) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_tail_call_sites) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_call_sites) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_source_call_sites) protected: virtual DeclarationLocation* GetDeclarationLocation(); diff --git a/src/apps/debugger/dwarf/Dwarf.h b/src/apps/debugger/dwarf/Dwarf.h index 1e9c99bc74..06dd514b7b 100644 --- a/src/apps/debugger/dwarf/Dwarf.h +++ b/src/apps/debugger/dwarf/Dwarf.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_H @@ -64,11 +65,16 @@ enum { DW_TAG_imported_unit = 0x3d, DW_TAG_condition = 0x3f, DW_TAG_shared_type = 0x40, + DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, DW_TAG_lo_user = 0x4080, DW_TAG_GNU_template_parameter_pack = 0x4107, DW_TAG_GNU_formal_parameter_pack = 0x4108, + DW_TAG_GNU_call_site = 0x4109, + DW_TAG_GNU_call_site_parameter = 0x410a, DW_TAG_hi_user = 0xffff }; @@ -166,7 +172,37 @@ enum { DW_AT_elemental = 0x66, // flag DW_AT_pure = 0x67, // flag DW_AT_recursive = 0x68, // flag + DW_AT_signature = 0x69, // reference + DW_AT_main_subprogram = 0x6a, // flag + DW_AT_data_bit_offset = 0x6b, // constant + DW_AT_const_expr = 0x6c, // flag + DW_AT_enum_class = 0x6d, // flag + DW_AT_linkage_name = 0x6e, // string + // TODO: proposed DWARF5 final values +/* DW_AT_call_site_value = 0x6f, // exprloc + DW_AT_call_site_data_value = 0x70, // exprloc + DW_AT_call_site_target = 0x71, // exprloc + DW_AT_call_site_target_clobbered + = 0x72, // exprloc + DW_AT_tail_call = 0x73, // flag + DW_AT_all_tail_call_sites = 0x74, // flag + DW_AT_all_call_sites = 0x75, // flag + DW_AT_all_source_call_sites = 0x76, // flag +*/ DW_AT_lo_user = 0x2000, + DW_AT_call_site_value = 0x2111, // exprloc + DW_AT_call_site_data_value + = 0x2112, // exprloc + DW_AT_call_site_target + = 0x2113, // exprloc + DW_AT_call_site_target_clobbered + = 0x2114, // exprloc + DW_AT_tail_call = 0x2115, // flag + DW_AT_all_tail_call_sites + = 0x2116, // flag + DW_AT_all_call_sites = 0x2117, // flag + DW_AT_all_source_call_sites + = 0x2118, // flag DW_AT_hi_user = 0x3fff }; @@ -195,6 +231,12 @@ enum { DW_FORM_ref8 = 0x14, // reference DW_FORM_ref_udata = 0x15, // reference DW_FORM_indirect = 0x16, // form in .debug_info + DW_FORM_sec_offset = 0x17, // lineptr, loclistptr, macptr, rangelistptr + DW_FORM_exprloc = 0x18, // dwarf expression + DW_FORM_flag_present + = 0x19, // flag + DW_FORM_ref_sig8 = 0x20 // reference + }; // expression operation diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp index 14ba4bbb7b..02322bf567 100644 --- a/src/apps/debugger/dwarf/DwarfFile.cpp +++ b/src/apps/debugger/dwarf/DwarfFile.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2012, Rene Gollent, rene@gollent.com. + * Copyright 2012-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -1253,7 +1253,17 @@ DwarfFile::_ParseEntryAttributes(DataReader& dataReader, case DW_FORM_ref_udata: value = dataReader.ReadUnsignedLEB128(0); break; + case DW_FORM_exprloc: + value = dataReader.ReadUnsignedLEB128(0); + break; + case DW_FORM_flag_present: + attributeValue.SetToFlag(dataReader.Read(0) != 0); + break; + case DW_FORM_ref_sig8: + value = dataReader.Read(0); + break; case DW_FORM_indirect: + case DW_FORM_sec_offset: default: WARNING("Unsupported attribute form: %" B_PRIu32 "\n", attributeForm); @@ -1322,6 +1332,10 @@ DwarfFile::_ParseEntryAttributes(DataReader& dataReader, case ATTRIBUTE_CLASS_STRING: // already set break; + case ATTRIBUTE_CLASS_EXPRESSION: + // TODO: implement + dataReader.Skip(value); + break; } if (dataReader.HasOverflow()) { diff --git a/src/apps/debugger/dwarf/DwarfUtils.cpp b/src/apps/debugger/dwarf/DwarfUtils.cpp index f32816101e..88fd0de2f9 100644 --- a/src/apps/debugger/dwarf/DwarfUtils.cpp +++ b/src/apps/debugger/dwarf/DwarfUtils.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2012, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -39,6 +39,67 @@ DwarfUtils::GetDIEName(const DebugInfoEntry* entry, BString& _name) } +/*static*/ void +DwarfUtils::GetDIETypeName(const DebugInfoEntry* entry, BString& _name) +{ + const DIEType* type = dynamic_cast(entry); + if (type == NULL) + return; + + const DIEModifiedType* modifiedType = dynamic_cast( + type); + BString typeName; + BString modifier; + + if (modifiedType != NULL) { + const DIEType* baseType = type; + while ((modifiedType = dynamic_cast( + baseType)) != NULL) { + switch (modifiedType->Tag()) { + case DW_TAG_pointer_type: + modifier.Prepend("*"); + break; + case DW_TAG_reference_type: + modifier.Prepend("&"); + break; + case DW_TAG_const_type: + modifier.Prepend(" const "); + break; + default: + break; + } + + baseType = modifiedType->GetType(); + } + type = baseType; + } + + // if the parameter has no type associated, + // then it's the unspecified type. + if (type == NULL) + typeName = "void"; + else + GetFullyQualifiedDIEName(type, typeName); + + if (modifier.Length() > 0) { + if (modifier[modifier.Length() - 1] == ' ') + modifier.Truncate(modifier.Length() - 1); + + // if the modifier has a leading const, treat it + // as the degenerate case and prepend it to the + // type name since that's the more typically used + // representation in source + if (modifier[0] == ' ') { + typeName.Prepend("const "); + modifier.Remove(0, 7); + } + typeName += modifier; + } + + _name = typeName; +} + + /*static*/ void DwarfUtils::GetFullDIEName(const DebugInfoEntry* entry, BString& _name) { @@ -62,9 +123,13 @@ DwarfUtils::GetFullDIEName(const DebugInfoEntry* entry, BString& _name) } } - // we found no name for this entry whatsoever, abort. - if (name == NULL) + if (name == NULL) { + if (dynamic_cast(entry) != NULL) + GetDIETypeName(entry, _name); + + // we found no name for this entry whatsoever, abort. return; + } generatedName = name; @@ -98,51 +163,7 @@ DwarfUtils::GetFullDIEName(const DebugInfoEntry* entry, BString& _name) BString paramName; BString modifier; DIEType* type = parameter->GetType(); - if (DIEModifiedType* modifiedType = dynamic_cast( - type)) { - DIEType* baseType = type; - while ((modifiedType = dynamic_cast( - baseType)) != NULL) { - switch (modifiedType->Tag()) { - case DW_TAG_pointer_type: - modifier.Prepend("*"); - break; - case DW_TAG_reference_type: - modifier.Prepend("&"); - break; - case DW_TAG_const_type: - modifier.Prepend(" const "); - break; - default: - break; - } - - baseType = modifiedType->GetType(); - } - type = baseType; - } - - // if the parameter has no type associated, - // then it's the unspecified type. - if (type == NULL) - paramName = "void"; - else - GetFullyQualifiedDIEName(type, paramName); - - if (modifier.Length() > 0) { - if (modifier[modifier.Length() - 1] == ' ') - modifier.Truncate(modifier.Length() - 1); - - // if the modifier has a leading const, treat it - // as the degenerate case and prepend it to the - // type name since that's the more typically used - // representation in source - if (modifier[0] == ' ') { - paramName.Prepend("const "); - modifier.Remove(0, 7); - } - paramName += modifier; - } + GetDIETypeName(type, paramName); if (firstParameter) firstParameter = false; @@ -158,7 +179,6 @@ DwarfUtils::GetFullDIEName(const DebugInfoEntry* entry, BString& _name) generatedName += "void"; generatedName += ")"; } - _name = generatedName; } diff --git a/src/apps/debugger/dwarf/DwarfUtils.h b/src/apps/debugger/dwarf/DwarfUtils.h index 092aa75643..1bedfd0802 100644 --- a/src/apps/debugger/dwarf/DwarfUtils.h +++ b/src/apps/debugger/dwarf/DwarfUtils.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_UTILS_H @@ -17,6 +18,8 @@ class DwarfUtils { public: static void GetDIEName(const DebugInfoEntry* entry, BString& _name); + static void GetDIETypeName(const DebugInfoEntry* entry, + BString& _name); static void GetFullDIEName(const DebugInfoEntry* entry, BString& _name); static void GetFullyQualifiedDIEName( diff --git a/src/apps/debugger/dwarf/TagNames.cpp b/src/apps/debugger/dwarf/TagNames.cpp index 4a9b4b5ff2..236c1a960f 100644 --- a/src/apps/debugger/dwarf/TagNames.cpp +++ b/src/apps/debugger/dwarf/TagNames.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -75,11 +76,18 @@ static const tag_name_info kTagNameInfos[] = { ENTRY(imported_unit), ENTRY(condition), ENTRY(shared_type), + ENTRY(type_unit), + ENTRY(rvalue_reference_type), + ENTRY(template_alias), + ENTRY(GNU_template_parameter_pack), + ENTRY(GNU_formal_parameter_pack), + ENTRY(GNU_call_site), + ENTRY(GNU_call_site_parameter), {} }; -static const uint32 kTagNameInfoCount = DW_TAG_shared_type + 1; +static const uint32 kTagNameInfoCount = DW_TAG_template_alias + 5; static const char* sTagNames[kTagNameInfoCount]; static struct InitTagNames { @@ -87,7 +95,12 @@ static struct InitTagNames { { for (uint32 i = 0; kTagNameInfos[i].name != NULL; i++) { const tag_name_info& info = kTagNameInfos[i]; - sTagNames[info.tag] = info.name; + if (info.tag <= DW_TAG_template_alias) + sTagNames[info.tag] = info.name; + else { + sTagNames[DW_TAG_template_alias + 1 + (info.tag + - DW_TAG_GNU_template_parameter_pack)] = info.name; + } } } } sInitTagNames; @@ -96,5 +109,13 @@ static struct InitTagNames { const char* get_entry_tag_name(uint16 tag) { - return tag < kTagNameInfoCount ? sTagNames[tag] : NULL; + if (tag <= DW_TAG_template_alias) + return sTagNames[tag]; + else if (tag >= DW_TAG_GNU_template_parameter_pack + && tag <= DW_TAG_GNU_call_site_parameter) { + return sTagNames[DW_TAG_template_alias + 1 + (tag + - DW_TAG_GNU_template_parameter_pack)]; + } + + return NULL; } diff --git a/src/apps/debugger/jobs/LoadSourceCodeJob.cpp b/src/apps/debugger/jobs/LoadSourceCodeJob.cpp index 4cb60a0a31..402a9ab711 100644 --- a/src/apps/debugger/jobs/LoadSourceCodeJob.cpp +++ b/src/apps/debugger/jobs/LoadSourceCodeJob.cpp @@ -82,6 +82,18 @@ LoadSourceCodeJob::Do() locker.Lock(); if (error == B_OK) { if (fFunctionInstance->SourceCodeState() == FUNCTION_SOURCE_LOADING) { + // various parts of the debugger expect functions to have only + // one of source or disassembly available. As such, if the current + // function had source code previously active, unset it when + // explicitly asked for disassembly. This needs to be done first + // since Function will clear the disassembled code states of all + // its child instances. + if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) { + FileSourceCode* sourceCode = function->GetSourceCode(); + function->SetSourceCode(sourceCode, + FUNCTION_SOURCE_NOT_LOADED); + } + fFunctionInstance->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED); sourceCode->ReleaseReference(); diff --git a/src/apps/debugger/model/SyscallInfo.cpp b/src/apps/debugger/model/SyscallInfo.cpp new file mode 100644 index 0000000000..e6b6ea47dc --- /dev/null +++ b/src/apps/debugger/model/SyscallInfo.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + +#include "SyscallInfo.h" + +#include + + +SyscallInfo::SyscallInfo() + : + fStartTime(0), + fEndTime(0), + fReturnValue(0), + fSyscall(0) +{ + memset(fArguments, 0, sizeof(fArguments)); +} + + +SyscallInfo::SyscallInfo(const SyscallInfo& other) + : + fStartTime(other.fStartTime), + fEndTime(other.fEndTime), + fReturnValue(other.fReturnValue), + fSyscall(other.fSyscall) +{ + memcpy(fArguments, other.fArguments, sizeof(fArguments)); +} + + +SyscallInfo::SyscallInfo(bigtime_t startTime, bigtime_t endTime, + uint64 returnValue, uint32 syscall, const uint8* args) + : + fStartTime(startTime), + fEndTime(endTime), + fReturnValue(returnValue), + fSyscall(syscall) +{ + memcpy(fArguments, args, sizeof(fArguments)); +} + + +void +SyscallInfo::SetTo(bigtime_t startTime, bigtime_t endTime, uint64 returnValue, + uint32 syscall, const uint8* args) +{ + fStartTime = startTime; + fEndTime = endTime; + fReturnValue = returnValue; + fSyscall = syscall; + memcpy(fArguments, args, sizeof(fArguments)); +} diff --git a/src/apps/debugger/model/SyscallInfo.h b/src/apps/debugger/model/SyscallInfo.h new file mode 100644 index 0000000000..4bb597f037 --- /dev/null +++ b/src/apps/debugger/model/SyscallInfo.h @@ -0,0 +1,43 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef SYSCALL_INFO_H +#define SYSCALL_INFO_H + +#include "Types.h" + + +class SyscallInfo { +public: + SyscallInfo(); + SyscallInfo(const SyscallInfo& other); + SyscallInfo(bigtime_t startTime, + bigtime_t endTime, + uint64 returnValue, + uint32 syscall, + const uint8* args); + + void SetTo(bigtime_t startTime, + bigtime_t endTime, + uint64 returnValue, + uint32 syscall, + const uint8* args); + + bigtime_t StartTime() const { return fStartTime; } + bigtime_t EndTime() const { return fEndTime; } + uint64 ReturnValue() const { return fReturnValue; } + uint32 Syscall() const { return fSyscall; } + + const uint8* Arguments() const { return fArguments; } + +private: + bigtime_t fStartTime; + bigtime_t fEndTime; + uint64 fReturnValue; + uint32 fSyscall; + uint8 fArguments[128]; +}; + + +#endif // SYSCALL_INFO_H diff --git a/src/apps/debugger/model/Team.cpp b/src/apps/debugger/model/Team.cpp index af38083a0d..47ca84dc99 100644 --- a/src/apps/debugger/model/Team.cpp +++ b/src/apps/debugger/model/Team.cpp @@ -1,13 +1,12 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #include "Team.h" -#include - #include #include @@ -78,7 +77,9 @@ Team::Team(team_id teamID, TeamMemory* teamMemory, Architecture* architecture, fTeamMemory(teamMemory), fTypeInformation(typeInformation), fArchitecture(architecture), - fDebugInfo(debugInfo) + fDebugInfo(debugInfo), + fStopOnImageLoad(false), + fStopImageNameListEnabled(false) { fDebugInfo->AcquireReference(); } @@ -273,6 +274,43 @@ Team::Images() const } +bool +Team::AddStopImageName(const BString& name) +{ + if (!fStopImageNames.Add(name)) + return false; + + fStopImageNames.Sort(); + + NotifyStopImageNameAdded(name); + return true; +} + + +void +Team::RemoveStopImageName(const BString& name) +{ + fStopImageNames.Remove(name); + NotifyStopImageNameRemoved(name); +} + + +void +Team::SetStopOnImageLoad(bool enabled, bool useImageNameList) +{ + fStopOnImageLoad = enabled; + fStopImageNameListEnabled = useImageNameList; + NotifyStopOnImageLoadChanged(enabled, useImageNameList); +} + + +const BStringList& +Team::StopImageNames() const +{ + return fStopImageNames; +} + + bool Team::AddBreakpoint(Breakpoint* breakpoint) { @@ -613,6 +651,53 @@ Team::NotifyImageDebugInfoChanged(Image* image) } +void +Team::NotifyStopOnImageLoadChanged(bool enabled, bool useImageNameList) +{ + for (ListenerList::Iterator it = fListeners.GetIterator(); + Listener* listener = it.Next();) { + listener->StopOnImageLoadSettingsChanged( + ImageLoadEvent(TEAM_EVENT_IMAGE_LOAD_SETTINGS_CHANGED, this, + enabled, useImageNameList)); + } +} + + +void +Team::NotifyStopImageNameAdded(const BString& name) +{ + for (ListenerList::Iterator it = fListeners.GetIterator(); + Listener* listener = it.Next();) { + listener->StopOnImageLoadNameAdded( + ImageLoadNameEvent(TEAM_EVENT_IMAGE_LOAD_NAME_ADDED, this, name)); + } +} + + +void +Team::NotifyStopImageNameRemoved(const BString& name) +{ + for (ListenerList::Iterator it = fListeners.GetIterator(); + Listener* listener = it.Next();) { + listener->StopOnImageLoadNameRemoved( + ImageLoadNameEvent(TEAM_EVENT_IMAGE_LOAD_NAME_REMOVED, this, + name)); + } +} + + +void +Team::NotifyConsoleOutputReceived(int32 fd, const BString& output) +{ + for (ListenerList::Iterator it = fListeners.GetIterator(); + Listener* listener = it.Next();) { + listener->ConsoleOutputReceived( + ConsoleOutputEvent(TEAM_EVENT_CONSOLE_OUTPUT_RECEIVED, this, + fd, output)); + } +} + + void Team::NotifyUserBreakpointChanged(UserBreakpoint* breakpoint) { @@ -719,6 +804,31 @@ Team::ImageEvent::ImageEvent(uint32 type, Image* image) } +// #pragma mark - ImageLoadEvent + + +Team::ImageLoadEvent::ImageLoadEvent(uint32 type, Team* team, + bool stopOnImageLoad, bool stopImageNameListEnabled) + : + Event(type, team), + fStopOnImageLoad(stopOnImageLoad), + fStopImageNameListEnabled(stopImageNameListEnabled) +{ +} + + +// #pragma mark - ImageLoadNameEvent + + +Team::ImageLoadNameEvent::ImageLoadNameEvent(uint32 type, Team* team, + const BString& name) + : + Event(type, team), + fImageName(name) +{ +} + + // #pragma mark - BreakpointEvent @@ -731,6 +841,19 @@ Team::BreakpointEvent::BreakpointEvent(uint32 type, Team* team, } +// #pragma mark - ConsoleOutputEvent + + +Team::ConsoleOutputEvent::ConsoleOutputEvent(uint32 type, Team* team, + int32 fd, const BString& output) + : + Event(type, team), + fDescriptor(fd), + fOutput(output) +{ +} + + // #pragma mark - DebugReportEvent @@ -823,6 +946,32 @@ Team::Listener::ImageDebugInfoChanged(const Team::ImageEvent& event) } +void +Team::Listener::StopOnImageLoadSettingsChanged( + const Team::ImageLoadEvent& event) +{ +} + + +void +Team::Listener::StopOnImageLoadNameAdded(const Team::ImageLoadNameEvent& event) +{ +} + + +void +Team::Listener::StopOnImageLoadNameRemoved( + const Team::ImageLoadNameEvent& event) +{ +} + + +void +Team::Listener::ConsoleOutputReceived(const Team::ConsoleOutputEvent& event) +{ +} + + void Team::Listener::BreakpointAdded(const Team::BreakpointEvent& event) { diff --git a/src/apps/debugger/model/Team.h b/src/apps/debugger/model/Team.h index 4b89c02c21..5428084796 100644 --- a/src/apps/debugger/model/Team.h +++ b/src/apps/debugger/model/Team.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_H @@ -7,6 +8,7 @@ #include +#include #include @@ -32,6 +34,12 @@ enum { TEAM_EVENT_IMAGE_DEBUG_INFO_CHANGED, + TEAM_EVENT_IMAGE_LOAD_SETTINGS_CHANGED, + TEAM_EVENT_IMAGE_LOAD_NAME_ADDED, + TEAM_EVENT_IMAGE_LOAD_NAME_REMOVED, + + TEAM_EVENT_CONSOLE_OUTPUT_RECEIVED, + TEAM_EVENT_BREAKPOINT_ADDED, TEAM_EVENT_BREAKPOINT_REMOVED, TEAM_EVENT_USER_BREAKPOINT_CHANGED, @@ -41,11 +49,13 @@ enum { TEAM_EVENT_WATCHPOINT_CHANGED, TEAM_EVENT_DEBUG_REPORT_CHANGED + }; class Architecture; class Breakpoint; +class BStringList; class Function; class FunctionID; class FunctionInstance; @@ -63,8 +73,11 @@ class Team { public: class Event; class BreakpointEvent; + class ConsoleOutputEvent; class DebugReportEvent; class ImageEvent; + class ImageLoadEvent; + class ImageLoadNameEvent; class ThreadEvent; class UserBreakpointEvent; class WatchpointEvent; @@ -112,6 +125,17 @@ public: Image* ImageByAddress(target_addr_t address) const; const ImageList& Images() const; + bool AddStopImageName(const BString& name); + void RemoveStopImageName(const BString& name); + const BStringList& StopImageNames() const; + + void SetStopOnImageLoad(bool enabled, + bool useImageNameList); + bool StopOnImageLoad() const + { return fStopOnImageLoad; } + bool StopImageNameListEnabled() const + { return fStopImageNameListEnabled; } + bool AddBreakpoint(Breakpoint* breakpoint); // takes over reference (also on error) void RemoveBreakpoint(Breakpoint* breakpoint); @@ -178,6 +202,17 @@ public: // service methods for Image void NotifyImageDebugInfoChanged(Image* image); + // service methods for Image load settings + void NotifyStopOnImageLoadChanged(bool enabled, + bool useImageNameList); + void NotifyStopImageNameAdded(const BString& name); + void NotifyStopImageNameRemoved( + const BString& name); + + // service methods for console output + void NotifyConsoleOutputReceived( + int32 fd, const BString& output); + // breakpoint related service methods void NotifyUserBreakpointChanged( UserBreakpoint* breakpoint); @@ -214,6 +249,9 @@ private: BString fName; ThreadList fThreads; ImageList fImages; + bool fStopOnImageLoad; + bool fStopImageNameListEnabled; + BStringList fStopImageNames; BreakpointList fBreakpoints; WatchpointList fWatchpoints; UserBreakpointList fUserBreakpoints; @@ -256,6 +294,35 @@ protected: }; +class Team::ImageLoadEvent : public Event { +public: + ImageLoadEvent(uint32 type, Team* team, + bool stopOnImageLoad, + bool stopImageNameListEnabled); + + bool StopOnImageLoad() const + { return fStopOnImageLoad; } + bool StopImageNameListEnabled() const + { return fStopImageNameListEnabled; } + +private: + bool fStopOnImageLoad; + bool fStopImageNameListEnabled; +}; + + +class Team::ImageLoadNameEvent : public Event { +public: + ImageLoadNameEvent(uint32 type, Team* team, + const BString& name); + + const BString& ImageName() const { return fImageName; } + +private: + BString fImageName; +}; + + class Team::BreakpointEvent : public Event { public: BreakpointEvent(uint32 type, Team* team, @@ -268,6 +335,20 @@ protected: }; +class Team::ConsoleOutputEvent : public Event { +public: + ConsoleOutputEvent(uint32 type, Team* team, + int32 fd, const BString& output); + + int32 Descriptor() const { return fDescriptor; } + const BString& Output() const { return fOutput; } + +protected: + int32 fDescriptor; + BString fOutput; +}; + + class Team::DebugReportEvent : public Event { public: DebugReportEvent(uint32 type, Team* team, @@ -323,6 +404,16 @@ public: virtual void ImageDebugInfoChanged( const Team::ImageEvent& event); + virtual void StopOnImageLoadSettingsChanged( + const Team::ImageLoadEvent& event); + virtual void StopOnImageLoadNameAdded( + const Team::ImageLoadNameEvent& event); + virtual void StopOnImageLoadNameRemoved( + const Team::ImageLoadNameEvent& event); + + virtual void ConsoleOutputReceived( + const Team::ConsoleOutputEvent& event); + virtual void BreakpointAdded( const Team::BreakpointEvent& event); virtual void BreakpointRemoved( diff --git a/src/apps/debugger/model/Thread.cpp b/src/apps/debugger/model/Thread.cpp index a52c6e1600..fc74ea0f67 100644 --- a/src/apps/debugger/model/Thread.cpp +++ b/src/apps/debugger/model/Thread.cpp @@ -19,6 +19,7 @@ Thread::Thread(Team* team, thread_id threadID) fID(threadID), fState(THREAD_STATE_UNKNOWN), fReturnValueInfos(NULL), + fStopRequestPending(false), fStoppedReason(THREAD_STOPPED_UNKNOWN), fCpuState(NULL), fStackTrace(NULL) @@ -78,6 +79,7 @@ Thread::SetState(uint32 state, uint32 reason, const BString& info) SetCpuState(NULL); SetStackTrace(NULL); ClearReturnValueInfos(); + fStopRequestPending = false; } fTeam->NotifyThreadStateChanged(this); @@ -119,6 +121,12 @@ Thread::SetStackTrace(StackTrace* trace) fTeam->NotifyThreadStackTraceChanged(this); } +void +Thread::SetStopRequestPending() +{ + fStopRequestPending = true; +} + status_t Thread::AddReturnValueInfo(ReturnValueInfo* info) diff --git a/src/apps/debugger/model/Thread.h b/src/apps/debugger/model/Thread.h index 9f936c7822..8cfe3be537 100644 --- a/src/apps/debugger/model/Thread.h +++ b/src/apps/debugger/model/Thread.h @@ -71,6 +71,10 @@ public: StackTrace* GetStackTrace() const { return fStackTrace; } void SetStackTrace(StackTrace* trace); + bool StopRequestPending() const + { return fStopRequestPending; } + void SetStopRequestPending(); + ReturnValueInfoList* ReturnValueInfos() const { return fReturnValueInfos; } @@ -84,6 +88,7 @@ private: uint32 fState; ReturnValueInfoList* fReturnValueInfos; + bool fStopRequestPending; uint32 fStoppedReason; BString fStoppedReasonInfo; CpuState* fCpuState; diff --git a/src/apps/debugger/model/UserBreakpoint.cpp b/src/apps/debugger/model/UserBreakpoint.cpp index 0fa577931b..996eb6e666 100644 --- a/src/apps/debugger/model/UserBreakpoint.cpp +++ b/src/apps/debugger/model/UserBreakpoint.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -99,7 +100,8 @@ UserBreakpoint::UserBreakpoint(const UserBreakpointLocation& location) : fLocation(location), fValid(false), - fEnabled(false) + fEnabled(false), + fHidden(false) { } @@ -160,3 +162,10 @@ UserBreakpoint::SetEnabled(bool enabled) { fEnabled = enabled; } + + +void +UserBreakpoint::SetHidden(bool hidden) +{ + fHidden = hidden; +} diff --git a/src/apps/debugger/model/UserBreakpoint.h b/src/apps/debugger/model/UserBreakpoint.h index 43f23fcc03..cf4cfe3286 100644 --- a/src/apps/debugger/model/UserBreakpoint.h +++ b/src/apps/debugger/model/UserBreakpoint.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef USER_BREAKPOINT_H @@ -100,6 +101,9 @@ public: void SetEnabled(bool enabled); // BreakpointManager only + bool IsHidden() const { return fHidden; } + void SetHidden(bool hidden); + private: typedef BObjectList InstanceList; @@ -108,6 +112,7 @@ private: InstanceList fInstances; bool fValid; bool fEnabled; + bool fHidden; }; diff --git a/src/apps/debugger/settings/BreakpointSetting.cpp b/src/apps/debugger/settings/BreakpointSetting.cpp index ca960f34d3..03ade77aa7 100644 --- a/src/apps/debugger/settings/BreakpointSetting.cpp +++ b/src/apps/debugger/settings/BreakpointSetting.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -20,7 +21,8 @@ BreakpointSetting::BreakpointSetting() fSourceFile(), fSourceLocation(), fRelativeAddress(0), - fEnabled(false) + fEnabled(false), + fHidden(false) { } @@ -31,7 +33,8 @@ BreakpointSetting::BreakpointSetting(const BreakpointSetting& other) fSourceFile(other.fSourceFile), fSourceLocation(other.fSourceLocation), fRelativeAddress(other.fRelativeAddress), - fEnabled(other.fEnabled) + fEnabled(other.fEnabled), + fHidden(other.fHidden) { if (fFunctionID != NULL) fFunctionID->AcquireReference(); @@ -45,7 +48,8 @@ BreakpointSetting::~BreakpointSetting() status_t -BreakpointSetting::SetTo(const UserBreakpointLocation& location, bool enabled) +BreakpointSetting::SetTo(const UserBreakpointLocation& location, bool enabled, + bool hidden) { _Unset(); @@ -59,6 +63,7 @@ BreakpointSetting::SetTo(const UserBreakpointLocation& location, bool enabled) fSourceLocation = location.GetSourceLocation(); fRelativeAddress = location.RelativeAddress(); fEnabled = enabled; + fHidden = hidden; return B_OK; } @@ -92,6 +97,9 @@ BreakpointSetting::SetTo(const BMessage& archive) if (archive.FindBool("enabled", &fEnabled) != B_OK) fEnabled = false; + if (archive.FindBool("hidden", &fHidden) != B_OK) + fHidden = false; + return B_OK; } @@ -113,7 +121,8 @@ BreakpointSetting::WriteTo(BMessage& archive) const != B_OK || (error = archive.AddUInt64("relativeAddress", fRelativeAddress)) != B_OK - || (error = archive.AddBool("enabled", fEnabled)) != B_OK) { + || (error = archive.AddBool("enabled", fEnabled)) != B_OK + || (error = archive.AddBool("hidden", fHidden)) != B_OK) { return error; } @@ -137,6 +146,7 @@ BreakpointSetting::operator=(const BreakpointSetting& other) fSourceLocation = other.fSourceLocation; fRelativeAddress = other.fRelativeAddress; fEnabled = other.fEnabled; + fHidden = other.fHidden; return *this; } diff --git a/src/apps/debugger/settings/BreakpointSetting.h b/src/apps/debugger/settings/BreakpointSetting.h index 964a0e552f..90d0a03449 100644 --- a/src/apps/debugger/settings/BreakpointSetting.h +++ b/src/apps/debugger/settings/BreakpointSetting.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef BREAKPOINT_SETTING_H @@ -27,7 +28,7 @@ public: ~BreakpointSetting(); status_t SetTo(const UserBreakpointLocation& location, - bool enabled); + bool enabled, bool hidden); status_t SetTo(const BMessage& archive); status_t WriteTo(BMessage& archive) const; @@ -39,6 +40,7 @@ public: { return fRelativeAddress; } bool IsEnabled() const { return fEnabled; } + bool IsHidden() const { return fHidden; } BreakpointSetting& operator=(const BreakpointSetting& other); @@ -51,6 +53,7 @@ private: SourceLocation fSourceLocation; target_addr_t fRelativeAddress; bool fEnabled; + bool fHidden; }; diff --git a/src/apps/debugger/settings/TeamSettings.cpp b/src/apps/debugger/settings/TeamSettings.cpp index 605202dcf8..cf3154151c 100644 --- a/src/apps/debugger/settings/TeamSettings.cpp +++ b/src/apps/debugger/settings/TeamSettings.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -61,7 +62,7 @@ TeamSettings::SetTo(Team* team) return B_NO_MEMORY; status_t error = breakpointSetting->SetTo(breakpoint->Location(), - breakpoint->IsEnabled()); + breakpoint->IsEnabled(), breakpoint->IsHidden()); if (error == B_OK && !fBreakpoints.AddItem(breakpointSetting)) error = B_NO_MEMORY; if (error != B_OK) { diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index 9ed4657440..cb00459c6d 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef USER_INTERFACE_H @@ -81,7 +82,8 @@ public: virtual ~UserInterfaceListener(); virtual void FunctionSourceCodeRequested( - FunctionInstance* function) = 0; + FunctionInstance* function, + bool forceDisassembly = false) = 0; virtual void SourceEntryLocateRequested( const char* sourcePath, const char* locatedPath) = 0; @@ -90,10 +92,11 @@ public: ValueNodeContainer* container, ValueNode* valueNode) = 0; virtual void ThreadActionRequested(thread_id threadID, - uint32 action) = 0; + uint32 action, + target_addr_t address = 0) = 0; virtual void SetBreakpointRequested(target_addr_t address, - bool enabled) = 0; + bool enabled, bool hidden = false) = 0; virtual void SetBreakpointEnabledRequested( UserBreakpoint* breakpoint, bool enabled) = 0; @@ -103,6 +106,13 @@ public: UserBreakpoint* breakpoint) = 0; // TODO: Consolidate those! + virtual void SetStopOnImageLoadRequested(bool enabled, + bool useImageNames) = 0; + virtual void AddStopImageNameRequested( + const char* name) = 0; + virtual void RemoveStopImageNameRequested( + const char* name) = 0; + virtual void SetWatchpointRequested(target_addr_t address, uint32 type, int32 length, bool enabled) = 0; @@ -120,6 +130,8 @@ public: virtual void DebugReportRequested(entry_ref* path) = 0; + virtual void TeamRestartRequested() = 0; + virtual bool UserInterfaceQuitRequested( QuitOption quitOption = QUIT_OPTION_ASK_USER) = 0; diff --git a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp index 1293e2f6ad..6a38146d52 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp @@ -27,8 +27,9 @@ enum { - MSG_NAVIGATE_PREVIOUS_BLOCK = 'npbl', - MSG_NAVIGATE_NEXT_BLOCK = 'npnl' + MSG_NAVIGATE_PREVIOUS_BLOCK = 'npbl', + MSG_NAVIGATE_NEXT_BLOCK = 'npnl', + MSG_MEMORY_BLOCK_RETRIEVED = 'mbre', }; @@ -52,8 +53,7 @@ InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener, InspectorWindow::~InspectorWindow() { - if (fCurrentBlock != NULL) - { + if (fCurrentBlock != NULL) { fCurrentBlock->RemoveListener(this); fCurrentBlock->ReleaseReference(); } @@ -186,15 +186,14 @@ InspectorWindow::_Init() void -InspectorWindow::MessageReceived(BMessage* msg) +InspectorWindow::MessageReceived(BMessage* message) { - switch (msg->what) { + switch (message->what) { case MSG_INSPECT_ADDRESS: { target_addr_t address = 0; bool addressValid = false; - if (msg->FindUInt64("address", &address) != B_OK) - { + if (message->FindUInt64("address", &address) != B_OK) { ExpressionParser parser; parser.SetSupportHexInput(true); const char* addressExpression = fAddressInput->Text(); @@ -222,15 +221,10 @@ InspectorWindow::MessageReceived(BMessage* msg) if (addressValid) { fCurrentAddress = address; - if (fCurrentBlock != NULL - && !fCurrentBlock->Contains(address)) { - fCurrentBlock->ReleaseReference(); - fCurrentBlock = NULL; - } - - if (fCurrentBlock == NULL) + if (fCurrentBlock == NULL + || !fCurrentBlock->Contains(address)) { fListener->InspectRequested(address, this); - else + } else fMemoryView->SetTargetAddress(fCurrentBlock, address); } break; @@ -238,10 +232,9 @@ InspectorWindow::MessageReceived(BMessage* msg) case MSG_NAVIGATE_PREVIOUS_BLOCK: case MSG_NAVIGATE_NEXT_BLOCK: { - if (fCurrentBlock != NULL) - { + if (fCurrentBlock != NULL) { target_addr_t address = fCurrentBlock->BaseAddress(); - if (msg->what == MSG_NAVIGATE_PREVIOUS_BLOCK) + if (message->what == MSG_NAVIGATE_PREVIOUS_BLOCK) address -= fCurrentBlock->Size(); else address += fCurrentBlock->Size(); @@ -252,9 +245,47 @@ InspectorWindow::MessageReceived(BMessage* msg) } break; } + case MSG_MEMORY_BLOCK_RETRIEVED: + { + TeamMemoryBlock* block = NULL; + status_t result; + if (message->FindPointer("block", + reinterpret_cast(&block)) != B_OK + || message->FindInt32("result", &result) != B_OK) { + break; + } + + { + AutoLocker< ::Team> teamLocker(fTeam); + block->RemoveListener(this); + } + + if (result == B_OK) { + if (fCurrentBlock != NULL) + fCurrentBlock->ReleaseReference(); + + fCurrentBlock = block; + fMemoryView->SetTargetAddress(block, fCurrentAddress); + fPreviousBlockButton->SetEnabled(true); + fNextBlockButton->SetEnabled(true); + } else { + BString errorMessage; + errorMessage.SetToFormat("Unable to read address 0x%" B_PRIx64 + ": %s", block->BaseAddress(), strerror(result)); + + BAlert* alert = new(std::nothrow) BAlert("Inspect address", + errorMessage.String(), "Close"); + if (alert == NULL) + break; + + alert->Go(NULL); + block->ReleaseReference(); + } + break; + } default: { - BWindow::MessageReceived(msg); + BWindow::MessageReceived(message); break; } } @@ -275,13 +306,21 @@ InspectorWindow::QuitRequested() void InspectorWindow::MemoryBlockRetrieved(TeamMemoryBlock* block) { - AutoLocker lock(this); - if (lock.IsLocked()) { - fCurrentBlock = block; - fMemoryView->SetTargetAddress(block, fCurrentAddress); - fPreviousBlockButton->SetEnabled(true); - fNextBlockButton->SetEnabled(true); - } + BMessage message(MSG_MEMORY_BLOCK_RETRIEVED); + message.AddPointer("block", block); + message.AddInt32("result", B_OK); + PostMessage(&message); +} + + +void +InspectorWindow::MemoryBlockRetrievalFailed(TeamMemoryBlock* block, + status_t result) +{ + BMessage message(MSG_MEMORY_BLOCK_RETRIEVED); + message.AddPointer("block", block); + message.AddInt32("result", result); + PostMessage(&message); } diff --git a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h index 320e344d9f..528701d9b8 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h +++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h @@ -41,6 +41,8 @@ public: // TeamMemoryBlock::Listener virtual void MemoryBlockRetrieved(TeamMemoryBlock* block); + virtual void MemoryBlockRetrievalFailed( + TeamMemoryBlock* block, status_t result); // MemoryView::Listener virtual void TargetAddressChanged(target_addr_t address); diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakConditionConfigWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/BreakConditionConfigWindow.cpp new file mode 100644 index 0000000000..a6428f2229 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/team_window/BreakConditionConfigWindow.cpp @@ -0,0 +1,455 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "BreakConditionConfigWindow.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "FunctionInstance.h" +#include "Image.h" +#include "ImageDebugInfo.h" +#include "MessageCodes.h" +#include "UserInterface.h" +#include "Team.h" + + +enum { + MSG_STOP_ON_THROWN_EXCEPTION_CHANGED = 'stec', + MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED = 'scec', + MSG_SET_STOP_FOR_ALL_IMAGES = 'sfai', + MSG_SET_STOP_FOR_CUSTOM_IMAGES = 'sfci', + MSG_IMAGE_NAME_SELECTION_CHANGED = 'insc', + MSG_ADD_IMAGE_NAME = 'anin', + MSG_REMOVE_IMAGE_NAME = 'arin' +}; + + +static int SortStringItems(const void* a, const void* b) +{ + BStringItem* item1 = *(BStringItem**)a; + BStringItem* item2 = *(BStringItem**)b; + + return strcmp(item1->Text(), item2->Text()); +} + + +static bool UpdateItemState(BListItem* item, void* enabled) +{ + item->SetEnabled((bool)enabled); + return false; +} + + +BreakConditionConfigWindow::BreakConditionConfigWindow(::Team* team, + UserInterfaceListener* listener, BHandler* target) + : + BWindow(BRect(), "Configure break conditions", B_FLOATING_WINDOW, + B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), + fTeam(team), + fListener(listener), + fExceptionThrown(NULL), + fExceptionCaught(NULL), + fStopOnImageLoad(NULL), + fStopImageConstraints(NULL), + fStopImageNames(NULL), + fStopImageNameInput(NULL), + fAddImageNameButton(NULL), + fRemoveImageNameButton(NULL), + fUseCustomImages(false), + fCloseButton(NULL), + fTarget(target) +{ + fTeam->AddListener(this); +} + + +BreakConditionConfigWindow::~BreakConditionConfigWindow() +{ + fTeam->RemoveListener(this); + BMessenger(fTarget).SendMessage(MSG_BREAK_CONDITION_CONFIG_WINDOW_CLOSED); +} + + +BreakConditionConfigWindow* +BreakConditionConfigWindow::Create(::Team* team, + UserInterfaceListener* listener, BHandler* target) +{ + BreakConditionConfigWindow* self = new BreakConditionConfigWindow( + team, listener, target); + + try { + self->_Init(); + } catch (...) { + delete self; + throw; + } + + return self; + +} + +void +BreakConditionConfigWindow::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_STOP_ON_THROWN_EXCEPTION_CHANGED: + { + _UpdateThrownBreakpoints(fExceptionThrown->Value() + == B_CONTROL_ON); + break; + } + + case MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED: + { + break; + } + + case MSG_SET_STOP_FOR_ALL_IMAGES: + { + fUseCustomImages = false; + fListener->SetStopOnImageLoadRequested( + fStopOnImageLoad->Value() == B_CONTROL_ON, + fUseCustomImages); + break; + } + + case MSG_SET_STOP_FOR_CUSTOM_IMAGES: + { + fUseCustomImages = true; + fListener->SetStopOnImageLoadRequested( + fStopOnImageLoad->Value() == B_CONTROL_ON, + fUseCustomImages); + break; + } + + case MSG_IMAGE_NAME_SELECTION_CHANGED: + { + if (!fUseCustomImages) + break; + + fRemoveImageNameButton->SetEnabled( + fStopImageNames->CurrentSelection() >= 0); + break; + } + + case MSG_STOP_ON_IMAGE_LOAD: + { + fListener->SetStopOnImageLoadRequested( + fStopOnImageLoad->Value() == B_CONTROL_ON, + fUseCustomImages); + break; + } + + case MSG_STOP_IMAGE_SETTINGS_CHANGED: + { + _UpdateStopImageButtons(); + break; + } + + case MSG_ADD_IMAGE_NAME: + { + BString imageName(fStopImageNameInput->Text()); + AutoLocker< ::Team> teamLocker(fTeam); + if (fTeam->StopImageNames().HasString(imageName)) + break; + + fStopImageNameInput->SetText(""); + fListener->AddStopImageNameRequested(imageName.String()); + break; + } + + case MSG_STOP_IMAGE_NAME_ADDED: + { + const char* imageName; + if (message->FindString("name", &imageName) != B_OK) + break; + + BStringItem* item = new(std::nothrow) BStringItem(imageName); + if (item == NULL) + break; + + ObjectDeleter itemDeleter(item); + if (!fStopImageNames->AddItem(item)) { + break; + } + itemDeleter.Detach(); + fStopImageNames->SortItems(SortStringItems); + break; + } + + case MSG_REMOVE_IMAGE_NAME: + { + BStringItem* item; + int32 selectedIndex; + AutoLocker< ::Team> teamLocker(fTeam); + int32 i = 0; + while ((selectedIndex = fStopImageNames->CurrentSelection(i++)) + >= 0) { + item = (BStringItem*)fStopImageNames->ItemAt(selectedIndex); + fListener->RemoveStopImageNameRequested(item->Text()); + } + break; + } + + case MSG_STOP_IMAGE_NAME_REMOVED: + { + const char* imageName; + if (message->FindString("name", &imageName) != B_OK) + break; + + for (int32 i = 0; i < fStopImageNames->CountItems(); i++) { + BStringItem* item = (BStringItem*)fStopImageNames->ItemAt(i); + if (strcmp(item->Text(), imageName) == 0) { + fStopImageNames->RemoveItem(i); + delete item; + } + } + break; + } + + + default: + BWindow::MessageReceived(message); + break; + } + +} + + +void +BreakConditionConfigWindow::Show() +{ + CenterOnScreen(); + BWindow::Show(); +} + + +void +BreakConditionConfigWindow::StopOnImageLoadSettingsChanged( + const Team::ImageLoadEvent& event) +{ + BMessage message(MSG_STOP_IMAGE_SETTINGS_CHANGED); + message.AddBool("enabled", event.StopOnImageLoad()); + message.AddBool("useNameList", event.StopImageNameListEnabled()); + PostMessage(&message); +} + + +void +BreakConditionConfigWindow::StopOnImageLoadNameAdded( + const Team::ImageLoadNameEvent& event) +{ + BMessage message(MSG_STOP_IMAGE_NAME_ADDED); + message.AddString("name", event.ImageName()); + PostMessage(&message); +} + + +void +BreakConditionConfigWindow::StopOnImageLoadNameRemoved( + const Team::ImageLoadNameEvent& event) +{ + BMessage message(MSG_STOP_IMAGE_NAME_REMOVED); + message.AddString("name", event.ImageName()); + PostMessage(&message); +} + + +void +BreakConditionConfigWindow::_Init() +{ + BBox* exceptionSettingsBox = new BBox("exceptionBox"); + exceptionSettingsBox->SetLabel("Exceptions"); + exceptionSettingsBox->AddChild(BLayoutBuilder::Group<>() + .AddGroup(B_VERTICAL) + .SetInsets(B_USE_DEFAULT_SPACING) + .Add(fExceptionThrown = new BCheckBox("exceptionThrown", + "Stop when an exception is thrown", + new BMessage(MSG_STOP_ON_THROWN_EXCEPTION_CHANGED))) + .Add(fExceptionCaught = new BCheckBox("exceptionCaught", + "Stop when an exception is caught", + new BMessage(MSG_STOP_ON_CAUGHT_EXCEPTION_CHANGED))) + .End() + .View()); + + fExceptionThrown->SetTarget(this); + fExceptionCaught->SetTarget(this); + + // TODO: enable once implemented + fExceptionCaught->SetEnabled(false); + + + BBox* imageSettingsBox = new BBox("imageBox"); + imageSettingsBox->SetLabel("Images"); + BMenu* stopImageMenu = new BMenu("stopImageTypesMenu"); + + stopImageMenu->AddItem(new BMenuItem("All", + new BMessage(MSG_SET_STOP_FOR_ALL_IMAGES))); + stopImageMenu->AddItem(new BMenuItem("Custom", + new BMessage(MSG_SET_STOP_FOR_CUSTOM_IMAGES))); + + fStopImageNames = new BListView("customImageList", + B_MULTIPLE_SELECTION_LIST); + fStopImageNames->SetSelectionMessage( + new BMessage(MSG_IMAGE_NAME_SELECTION_CHANGED)); + + imageSettingsBox->AddChild(BLayoutBuilder::Group<>() + .AddGroup(B_VERTICAL) + .SetInsets(B_USE_DEFAULT_SPACING) + .Add(fStopOnImageLoad = new BCheckBox("stopOnImage", + "Stop when an image is loaded", + new BMessage(MSG_STOP_ON_IMAGE_LOAD))) + .Add(fStopImageConstraints = new BMenuField( + "stopTypes", "Types:", stopImageMenu)) + .Add(new BScrollView("stopImageScroll", fStopImageNames, + 0, false, true)) + .Add(fStopImageNameInput = new BTextControl("stopImageName", + "Image:", NULL, NULL)) + .AddGroup(B_HORIZONTAL) + .AddGlue() + .Add(fAddImageNameButton = new BButton("Add", + new BMessage(MSG_ADD_IMAGE_NAME))) + .Add(fRemoveImageNameButton = new BButton("Remove", + new BMessage(MSG_REMOVE_IMAGE_NAME))) + .End() + .End() + .View()); + + font_height fontHeight; + be_plain_font->GetHeight(&fontHeight); + float minListHeight = 5 * (fontHeight.ascent + fontHeight.descent + + fontHeight.leading); + fStopImageNames->SetExplicitMinSize(BSize(B_SIZE_UNSET, minListHeight)); + + BLayoutBuilder::Group<>(this, B_VERTICAL) + .SetInsets(B_USE_DEFAULT_SPACING) + .Add(exceptionSettingsBox) + .Add(imageSettingsBox) + .AddGroup(B_HORIZONTAL) + .AddGlue() + .Add(fCloseButton = new BButton("Close", new BMessage( + B_QUIT_REQUESTED))) + .End(); + + + fCloseButton->SetTarget(this); + stopImageMenu->SetTargetForItems(this); + stopImageMenu->SetLabelFromMarked(true); + + AutoLocker< ::Team> teamLocker(fTeam); + _UpdateStopImageState(); + _UpdateExceptionState(); + +} + + +void +BreakConditionConfigWindow::_UpdateThrownBreakpoints(bool enable) +{ + AutoLocker< ::Team> teamLocker(fTeam); + for (ImageList::ConstIterator it = fTeam->Images().GetIterator(); + it.HasNext();) { + Image* image = it.Next(); + + ImageDebugInfo* info = image->GetImageDebugInfo(); + target_addr_t address; + if (_FindExceptionFunction(info, address) != B_OK) + continue; + + if (enable) + fListener->SetBreakpointRequested(address, true, true); + else + fListener->ClearBreakpointRequested(address); + } +} + + +status_t +BreakConditionConfigWindow::_FindExceptionFunction(ImageDebugInfo* info, + target_addr_t& _foundAddress) const +{ + if (info != NULL) { + FunctionInstance* instance = info->FunctionByName( + "__cxa_allocate_exception"); + if (instance == NULL) + instance = info->FunctionByName("__throw(void)"); + + if (instance != NULL) { + _foundAddress = instance->Address(); + return B_OK; + } + } + + return B_NAME_NOT_FOUND; +} + + +void +BreakConditionConfigWindow::_UpdateExceptionState() +{ + // check if the exception breakpoints are already installed + for (ImageList::ConstIterator it = fTeam->Images().GetIterator(); + it.HasNext();) { + Image* image = it.Next(); + + ImageDebugInfo* info = image->GetImageDebugInfo(); + target_addr_t address; + if (_FindExceptionFunction(info, address) != B_OK) + continue; + + if (fTeam->BreakpointAtAddress(address) != NULL) { + fExceptionThrown->SetValue(B_CONTROL_ON); + break; + } + } +} + + +void +BreakConditionConfigWindow::_UpdateStopImageState() +{ + fUseCustomImages = fTeam->StopImageNameListEnabled(); + fStopImageConstraints->Menu()->ItemAt(0)->SetMarked(!fUseCustomImages); + fStopImageConstraints->Menu()->ItemAt(1)->SetMarked(fUseCustomImages); + + fStopImageNames->MakeEmpty(); + const BStringList& imageNames = fTeam->StopImageNames(); + for (int32 i = 0; i < imageNames.CountStrings(); i++) { + BStringItem* item = new(std::nothrow) BStringItem( + imageNames.StringAt(i)); + if (item == NULL) + return; + item->SetEnabled(fUseCustomImages); + ObjectDeleter itemDeleter(item); + if (!fStopImageNames->AddItem(item)) + return; + itemDeleter.Detach(); + } + + _UpdateStopImageButtons(); +} + + +void +BreakConditionConfigWindow::_UpdateStopImageButtons() +{ + bool stopOnImageLoad = fTeam->StopOnImageLoad(); + fStopOnImageLoad->SetValue(stopOnImageLoad ? B_CONTROL_ON : B_CONTROL_OFF); + bool enabled = stopOnImageLoad && fUseCustomImages; + fStopImageConstraints->SetEnabled(stopOnImageLoad); + fAddImageNameButton->SetEnabled(enabled); + fRemoveImageNameButton->SetEnabled(enabled + && fStopImageNames->CurrentSelection() >= 0); + fStopImageNames->DoForEach(UpdateItemState, (void*)enabled); + fStopImageNameInput->TextView()->MakeEditable(enabled); +} diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakConditionConfigWindow.h b/src/apps/debugger/user_interface/gui/team_window/BreakConditionConfigWindow.h new file mode 100644 index 0000000000..e1478935f6 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/team_window/BreakConditionConfigWindow.h @@ -0,0 +1,81 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef BREAK_CONDITION_CONFIG_WINDOW_H +#define BREAK_CONDITION_CONFIG_WINDOW_H + + +#include + +#include "Team.h" + +#include "types/Types.h" + + +class BButton; +class BCheckBox; +class BListView; +class BMenuField; +class BTextControl; +class ImageDebugInfo; +class UserInterfaceListener; + + +class BreakConditionConfigWindow : public BWindow, private Team::Listener { +public: + BreakConditionConfigWindow(::Team* team, + UserInterfaceListener* listener, + BHandler* target); + + ~BreakConditionConfigWindow(); + + static BreakConditionConfigWindow* Create(::Team* team, + UserInterfaceListener* listener, + BHandler* target); + // throws + + virtual void MessageReceived(BMessage* message); + + virtual void Show(); + + // Team::Listener + virtual void StopOnImageLoadSettingsChanged( + const Team::ImageLoadEvent& event); + virtual void StopOnImageLoadNameAdded( + const Team::ImageLoadNameEvent& event); + virtual void StopOnImageLoadNameRemoved( + const Team::ImageLoadNameEvent& event); + + +private: + void _Init(); + void _UpdateThrownBreakpoints(bool enable); + status_t _FindExceptionFunction(ImageDebugInfo* info, + target_addr_t& _foundAddress) const; + + void _UpdateExceptionState(); + void _UpdateStopImageState(); + void _UpdateStopImageButtons(); + // must be called with team lock held + + + +private: + ::Team* fTeam; + UserInterfaceListener* fListener; + BCheckBox* fExceptionThrown; + BCheckBox* fExceptionCaught; + BCheckBox* fStopOnImageLoad; + BMenuField* fStopImageConstraints; + BListView* fStopImageNames; + BTextControl* fStopImageNameInput; + BButton* fAddImageNameButton; + BButton* fRemoveImageNameButton; + bool fUseCustomImages; + BButton* fCloseButton; + BHandler* fTarget; +}; + + +#endif // BREAK_CONDITION_CONFIG_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.cpp b/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.cpp index b1698c8f41..6b88b6316d 100644 --- a/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -11,12 +11,16 @@ #include +#include + #include #include +#include "Architecture.h" #include "FunctionID.h" #include "GuiSettingsUtils.h" #include "LocatableFile.h" +#include "MessageCodes.h" #include "table/TableColumns.h" #include "TargetAddressTableColumn.h" #include "Team.h" @@ -24,6 +28,73 @@ #include "Watchpoint.h" +// #pragma mark - BreakpointProxy + + +BreakpointProxy::BreakpointProxy(UserBreakpoint* breakpoint, + Watchpoint* watchpoint) + : + fBreakpoint(breakpoint), + fWatchpoint(watchpoint) +{ + if (fBreakpoint != NULL) + fBreakpoint->AcquireReference(); + + if (fWatchpoint != NULL) + fWatchpoint->AcquireReference(); +} + + +BreakpointProxy::~BreakpointProxy() +{ + if (fBreakpoint != NULL) + fBreakpoint->ReleaseReference(); + + if (fWatchpoint != NULL) + fWatchpoint->ReleaseReference(); +} + + +breakpoint_proxy_type +BreakpointProxy::Type() const +{ + return fBreakpoint != NULL ? BREAKPOINT_PROXY_TYPE_BREAKPOINT + : BREAKPOINT_PROXY_TYPE_WATCHPOINT; +} + + +// #pragma mark - ListInputFilter + + +class BreakpointListView::ListInputFilter : public BMessageFilter { +public: + ListInputFilter(BView* view) + : + BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_KEY_DOWN), + fTargetView(view) + { + } + + ~ListInputFilter() + { + } + + filter_result Filter(BMessage* message, BHandler** target) + { + const char* bytes; + if (message->FindString("bytes", &bytes) == B_OK + && bytes[0] == B_DELETE) { + BMessenger(fTargetView).SendMessage(MSG_CLEAR_BREAKPOINT); + } + + return B_DISPATCH_MESSAGE; + } + +private: + BView* fTargetView; +}; + + // #pragma mark - BreakpointsTableModel @@ -34,25 +105,23 @@ public: fTeam(team) { UpdateBreakpoint(NULL); - UpdateWatchpoint(NULL); } ~BreakpointsTableModel() { fTeam = NULL; UpdateBreakpoint(NULL); - UpdateWatchpoint(NULL); } - bool UpdateBreakpoint(UserBreakpoint* changedBreakpoint) + bool UpdateBreakpoint(BreakpointProxy* proxy) { if (fTeam == NULL) { for (int32 i = 0; - UserBreakpoint* breakpoint = fBreakpoints.ItemAt(i); + BreakpointProxy* proxy = fBreakpointProxies.ItemAt(i); i++) { - breakpoint->ReleaseReference(); + proxy->ReleaseReference(); } - fBreakpoints.MakeEmpty(); + fBreakpointProxies.MakeEmpty(); return true; } @@ -61,132 +130,126 @@ public: UserBreakpointList::ConstIterator it = fTeam->UserBreakpoints().GetIterator(); + int32 watchpointIndex = 0; UserBreakpoint* newBreakpoint = it.Next(); + Watchpoint* newWatchpoint = fTeam->WatchpointAt(watchpointIndex); int32 index = 0; + bool remove; // remove no longer existing breakpoints - while (UserBreakpoint* oldBreakpoint = fBreakpoints.ItemAt(index)) { - if (oldBreakpoint == newBreakpoint) { - if (oldBreakpoint == changedBreakpoint) - NotifyRowsChanged(index, 1); - index++; - newBreakpoint = it.Next(); - } else { + while (BreakpointProxy* oldProxy = fBreakpointProxies.ItemAt(index)) { + remove = false; + switch (oldProxy->Type()) { + case BREAKPOINT_PROXY_TYPE_BREAKPOINT: + { + UserBreakpoint* breakpoint = oldProxy->GetBreakpoint(); + if (breakpoint == newBreakpoint) { + if (breakpoint == proxy->GetBreakpoint()) + NotifyRowsChanged(index, 1); + ++index; + newBreakpoint = it.Next(); + } else + remove = true; + } + break; + + case BREAKPOINT_PROXY_TYPE_WATCHPOINT: + { + Watchpoint* watchpoint = oldProxy->GetWatchpoint(); + if (watchpoint == newWatchpoint) { + if (watchpoint == proxy->GetWatchpoint()) + NotifyRowsChanged(index, 1); + ++watchpointIndex; + ++index; + newWatchpoint = fTeam->WatchpointAt(watchpointIndex); + } else + remove = true; + } + break; + } + + if (remove) { // TODO: Not particularly efficient! - fBreakpoints.RemoveItemAt(index); - oldBreakpoint->ReleaseReference(); + fBreakpointProxies.RemoveItemAt(index); + oldProxy->ReleaseReference(); NotifyRowsRemoved(index, 1); } } // add new breakpoints - int32 countBefore = fBreakpoints.CountItems(); + int32 countBefore = fBreakpointProxies.CountItems(); + BreakpointProxy* newProxy = NULL; + BReference proxyReference; while (newBreakpoint != NULL) { - if (!fBreakpoints.AddItem(newBreakpoint)) + newProxy = new(std::nothrow) BreakpointProxy(newBreakpoint, NULL); + if (newProxy == NULL) return false; - newBreakpoint->AcquireReference(); + proxyReference.SetTo(newProxy, true); + if (!fBreakpointProxies.AddItem(newProxy)) + return false; + + proxyReference.Detach(); newBreakpoint = it.Next(); } - int32 count = fBreakpoints.CountItems(); + // add new watchpoints + while (newWatchpoint != NULL) { + newProxy = new(std::nothrow) BreakpointProxy(NULL, newWatchpoint); + if (newProxy == NULL) + return false; + + proxyReference.SetTo(newProxy, true); + if (!fBreakpointProxies.AddItem(newProxy)) + return false; + + proxyReference.Detach(); + newWatchpoint = fTeam->WatchpointAt(++watchpointIndex); + } + + + int32 count = fBreakpointProxies.CountItems(); if (count > countBefore) NotifyRowsAdded(countBefore, count - countBefore); return true; } - bool UpdateWatchpoint(Watchpoint* changedWatchpoint) - { - if (fTeam == NULL) { - for (int32 i = 0; - Watchpoint* watchpoint = fWatchpoints.ItemAt(i); - i++) { - watchpoint->ReleaseReference(); - } - fWatchpoints.MakeEmpty(); - - return true; - } - - AutoLocker locker(fTeam); - - int32 breakpointCount = fBreakpoints.CountItems(); - int32 index = 0; - int32 teamIndex = 0; - Watchpoint* newWatchpoint = fTeam->WatchpointAt(teamIndex); - // remove no longer existing breakpoints - while (Watchpoint* oldWatchpoint = fWatchpoints.ItemAt(index)) { - if (oldWatchpoint == newWatchpoint) { - if (oldWatchpoint == changedWatchpoint) - NotifyRowsChanged(index + breakpointCount, 1); - index++; - teamIndex++; - newWatchpoint = fTeam->WatchpointAt(teamIndex); - } else { - // TODO: Not particularly efficient! - fWatchpoints.RemoveItemAt(index); - oldWatchpoint->ReleaseReference(); - NotifyRowsRemoved(index + breakpointCount, 1); - } - } - - // add new breakpoints - int32 countBefore = fWatchpoints.CountItems(); - while (newWatchpoint != NULL) { - if (!fWatchpoints.AddItem(newWatchpoint)) - return false; - - newWatchpoint->AcquireReference(); - teamIndex++; - newWatchpoint = fTeam->WatchpointAt(teamIndex); - } - - int32 count = fWatchpoints.CountItems(); - if (count > countBefore) - NotifyRowsAdded(countBefore + breakpointCount, count - countBefore); - - return true; - } - virtual int32 CountColumns() const { - return 5; + return 3; } virtual int32 CountRows() const { - return fBreakpoints.CountItems() + fWatchpoints.CountItems(); + return fBreakpointProxies.CountItems(); } virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value) { - int32 breakpointCount = fBreakpoints.CountItems(); - if (rowIndex < breakpointCount) - return _GetBreakpointValueAt(rowIndex, columnIndex, value); + BreakpointProxy* proxy = fBreakpointProxies.ItemAt(rowIndex); + if (proxy == NULL) + return false; - return _GetWatchpointValueAt(rowIndex - breakpointCount, columnIndex, - value); + if (proxy->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) { + return _GetBreakpointValueAt(proxy->GetBreakpoint(), rowIndex, + columnIndex, value); + } + + return _GetWatchpointValueAt(proxy->GetWatchpoint(), rowIndex, + columnIndex, value); } - UserBreakpoint* BreakpointAt(int32 index) const + BreakpointProxy* BreakpointProxyAt(int32 index) const { - return fBreakpoints.ItemAt(index); - } - - Watchpoint* WatchpointAt(int32 index) const - { - return fWatchpoints.ItemAt(index - fBreakpoints.CountItems()); + return fBreakpointProxies.ItemAt(index); } private: - bool _GetBreakpointValueAt(int32 rowIndex, int32 columnIndex, - BVariant &value) + bool _GetBreakpointValueAt(UserBreakpoint* breakpoint, int32 rowIndex, + int32 columnIndex, BVariant &value) { - UserBreakpoint* breakpoint = fBreakpoints.ItemAt(rowIndex); - if (breakpoint == NULL) - return false; const UserBreakpointLocation& location = breakpoint->Location(); switch (columnIndex) { @@ -198,62 +261,75 @@ private: B_VARIANT_DONT_COPY_DATA); return true; case 2: - if (LocatableFile* sourceFile = location.SourceFile()) { - value.SetTo(sourceFile->Name(), B_VARIANT_DONT_COPY_DATA); - return true; - } - return false; - case 3: - if (location.SourceFile() != NULL) { - value.SetTo(location.GetSourceLocation().Line() + 1); - return true; - } - return false; - case 4: - if (location.SourceFile() == NULL) { + { + LocatableFile* sourceFile = location.SourceFile(); + BString data; + if (sourceFile != NULL) { + data.SetToFormat("%s:%" B_PRId32, sourceFile->Name(), + location.GetSourceLocation().Line() + 1); + } else { AutoLocker teamLocker(fTeam); if (UserBreakpointInstance* instance = breakpoint->InstanceAt(0)) { - value.SetTo(instance->Address()); - return true; + data.SetToFormat("%#" B_PRIx64, instance->Address()); } } - return false; + value.SetTo(data); + return true; + } default: return false; } } - bool _GetWatchpointValueAt(int32 rowIndex, int32 columnIndex, - BVariant& value) + bool _GetWatchpointValueAt(Watchpoint* watchpoint, int32 rowIndex, + int32 columnIndex, BVariant &value) { - Watchpoint* watchpoint = fWatchpoints.ItemAt(rowIndex); - if (watchpoint == NULL) - return false; - switch (columnIndex) { case 0: value.SetTo((int32)watchpoint->IsEnabled()); return true; case 1: - value.SetTo("Watchpoint"); + { + BString data; + data.SetToFormat("%s at 0x%" B_PRIx64 " (%" B_PRId32 " bytes)", + _WatchpointTypeToString(watchpoint->Type()), + watchpoint->Address(), watchpoint->Length()); + value.SetTo(data); return true; + } case 2: + { return false; - case 3: - return false; - case 4: - value.SetTo(watchpoint->Address()); - return true; + } default: return false; } } + const char* _WatchpointTypeToString(uint32 type) const + { + switch (type) { + case WATCHPOINT_CAPABILITY_FLAG_READ: + { + return "read"; + } + case WATCHPOINT_CAPABILITY_FLAG_WRITE: + { + return "write"; + } + case WATCHPOINT_CAPABILITY_FLAG_READ_WRITE: + { + return "read/write"; + } + default: + return NULL; + } + } + private: Team* fTeam; - BObjectList fBreakpoints; - BObjectList fWatchpoints; + BreakpointProxyList fBreakpointProxies; }; @@ -264,7 +340,6 @@ BreakpointListView::BreakpointListView(Team* team, Listener* listener) : BGroupView(B_VERTICAL), fTeam(team), - fBreakpoint(NULL), fBreakpointsTable(NULL), fBreakpointsTableModel(NULL), fListener(listener) @@ -280,12 +355,12 @@ BreakpointListView::~BreakpointListView() /*static*/ BreakpointListView* -BreakpointListView::Create(Team* team, Listener* listener) +BreakpointListView::Create(Team* team, Listener* listener, BView* filterTarget) { BreakpointListView* self = new BreakpointListView(team, listener); try { - self->_Init(); + self->_Init(filterTarget); } catch (...) { delete self; throw; @@ -302,46 +377,22 @@ BreakpointListView::UnsetListener() } -void -BreakpointListView::SetBreakpoint(UserBreakpoint* breakpoint, - Watchpoint* watchpoint) -{ - if (breakpoint == fBreakpoint) - return; - - if (fBreakpoint != NULL) - fBreakpoint->ReleaseReference(); - - fBreakpoint = breakpoint; - - if (fBreakpoint != NULL) { - fBreakpoint->AcquireReference(); - - for (int32 i = 0; - UserBreakpoint* other = fBreakpointsTableModel->BreakpointAt(i); - i++) { - if (fBreakpoint == other) { - fBreakpointsTable->SelectRow(i, false); - return; - } - } - } - - fBreakpointsTable->DeselectAllRows(); -} - - void BreakpointListView::UserBreakpointChanged(UserBreakpoint* breakpoint) { - fBreakpointsTableModel->UpdateBreakpoint(breakpoint); + if (breakpoint->IsHidden()) + return; + + BreakpointProxy proxy(breakpoint, NULL); + fBreakpointsTableModel->UpdateBreakpoint(&proxy); } void BreakpointListView::WatchpointChanged(Watchpoint* watchpoint) { - fBreakpointsTableModel->UpdateWatchpoint(watchpoint); + BreakpointProxy proxy(NULL, watchpoint); + fBreakpointsTableModel->UpdateBreakpoint(&proxy); } @@ -378,20 +429,22 @@ BreakpointListView::TableSelectionChanged(Table* table) return; TableSelectionModel* selectionModel = table->SelectionModel(); - UserBreakpoint* breakpoint = fBreakpointsTableModel->BreakpointAt( - selectionModel->RowAt(0)); - if (breakpoint != NULL) - fListener->BreakpointSelectionChanged(breakpoint); - else { - Watchpoint* watchpoint = fBreakpointsTableModel->WatchpointAt( - selectionModel->RowAt(0)); - fListener->WatchpointSelectionChanged(watchpoint); + BreakpointProxyList proxyList; + for (int32 i = 0; i < selectionModel->CountRows(); i++) { + BreakpointProxy* proxy = fBreakpointsTableModel->BreakpointProxyAt( + selectionModel->RowAt(i)); + if (proxy == NULL) + continue; + if (!proxyList.AddItem(proxy)) + return; } + + fListener->BreakpointSelectionChanged(proxyList); } void -BreakpointListView::_Init() +BreakpointListView::_Init(BView* filterTarget) { fBreakpointsTable = new Table("breakpoints list", 0, B_FANCY_BORDER); AddChild(fBreakpointsTable->ToView()); @@ -399,17 +452,15 @@ BreakpointListView::_Init() // columns fBreakpointsTable->AddColumn(new BoolStringTableColumn(0, "State", 70, 20, 1000, "Enabled", "Disabled")); - fBreakpointsTable->AddColumn(new StringTableColumn(1, "Function", 250, 40, + fBreakpointsTable->AddColumn(new StringTableColumn(1, "Location", 250, 40, 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); - fBreakpointsTable->AddColumn(new StringTableColumn(2, "File", 250, 40, - 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); - fBreakpointsTable->AddColumn(new Int32TableColumn(3, "Line", 60, 20, - 1000, B_TRUNCATE_END, B_ALIGN_RIGHT)); - fBreakpointsTable->AddColumn(new TargetAddressTableColumn(4, "Address", 100, - 20, 1000, B_TRUNCATE_END, B_ALIGN_RIGHT)); + fBreakpointsTable->AddColumn(new StringTableColumn(2, "File:Line/Address", + 250, 40, 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); - fBreakpointsTable->SetSelectionMode(B_SINGLE_SELECTION_LIST); + fBreakpointsTable->SetSelectionMode(B_MULTIPLE_SELECTION_LIST); fBreakpointsTable->AddTableListener(this); + fBreakpointsTable->AddFilter(new ListInputFilter(filterTarget)); + fBreakpointsTableModel = new BreakpointsTableModel(fTeam); fBreakpointsTable->SetTableModel(fBreakpointsTableModel); diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.h b/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.h index 317ca5be71..9045148abc 100644 --- a/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.h +++ b/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef BREAKPOINT_LIST_VIEW_H @@ -16,6 +17,31 @@ class UserBreakpoint; class Watchpoint; +enum breakpoint_proxy_type { + BREAKPOINT_PROXY_TYPE_BREAKPOINT = 0, + BREAKPOINT_PROXY_TYPE_WATCHPOINT = 1 +}; + + +class BreakpointProxy : public BReferenceable { +public: + BreakpointProxy(UserBreakpoint* breakpoint, + Watchpoint* watchpoint); + ~BreakpointProxy(); + + breakpoint_proxy_type Type() const; + + UserBreakpoint* GetBreakpoint() const { return fBreakpoint; } + Watchpoint* GetWatchpoint() const { return fWatchpoint; } + +private: + UserBreakpoint* fBreakpoint; + Watchpoint* fWatchpoint; +}; + +typedef BObjectList BreakpointProxyList; + + class BreakpointListView : public BGroupView, private TableListener { public: class Listener; @@ -25,14 +51,12 @@ public: Listener* listener); ~BreakpointListView(); - static BreakpointListView* Create(Team* team, Listener* listener); + static BreakpointListView* Create(Team* team, Listener* listener, + BView* filterTarget); // throws void UnsetListener(); - void SetBreakpoint(UserBreakpoint* breakpoint, - Watchpoint* watchpoint); - void UserBreakpointChanged( UserBreakpoint* breakpoint); void WatchpointChanged( @@ -43,17 +67,16 @@ public: private: class BreakpointsTableModel; + class ListInputFilter; private: // TableListener virtual void TableSelectionChanged(Table* table); - void _Init(); + void _Init(BView* filterTarget); private: Team* fTeam; - UserBreakpoint* fBreakpoint; - Watchpoint* fWatchpoint; Table* fBreakpointsTable; BreakpointsTableModel* fBreakpointsTableModel; Listener* fListener; @@ -65,10 +88,7 @@ public: virtual ~Listener(); virtual void BreakpointSelectionChanged( - UserBreakpoint* breakpoint) = 0; - - virtual void WatchpointSelectionChanged( - Watchpoint* watchpoint) = 0; + BreakpointProxyList& breakpoints) = 0; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp b/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp index 7095cdd183..f1eaacbc92 100644 --- a/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -27,9 +28,8 @@ BreakpointsView::BreakpointsView(Team* team, Listener* listener) : BGroupView(B_HORIZONTAL, 4.0f), fTeam(team), - fBreakpoint(NULL), - fWatchpoint(NULL), fListView(NULL), + fConfigureExceptionsButton(NULL), fToggleBreakpointButton(NULL), fRemoveBreakpointButton(NULL), fListener(listener) @@ -68,32 +68,6 @@ BreakpointsView::UnsetListener() } -void -BreakpointsView::SetBreakpoint(UserBreakpoint* breakpoint, Watchpoint* watchpoint) -{ - if (breakpoint == fBreakpoint && watchpoint == fWatchpoint) - return; - - if (fWatchpoint != NULL) - fWatchpoint->ReleaseReference(); - - if (fBreakpoint != NULL) - fBreakpoint->ReleaseReference(); - - fWatchpoint = watchpoint; - fBreakpoint = breakpoint; - - if (fBreakpoint != NULL) - fBreakpoint->AcquireReference(); - else if (fWatchpoint != NULL) - fWatchpoint->AcquireReference(); - - fListView->SetBreakpoint(breakpoint, watchpoint); - - _UpdateButtons(); -} - - void BreakpointsView::UserBreakpointChanged(UserBreakpoint* breakpoint) { @@ -117,37 +91,11 @@ BreakpointsView::MessageReceived(BMessage* message) { switch (message->what) { case MSG_ENABLE_BREAKPOINT: - if (fListener != NULL) { - if (fBreakpoint != NULL) { - fListener->SetBreakpointEnabledRequested(fBreakpoint, - true); - } else if (fWatchpoint != NULL) { - fListener->SetWatchpointEnabledRequested(fWatchpoint, - true); - } - } - break; case MSG_DISABLE_BREAKPOINT: - if (fListener != NULL) { - if (fBreakpoint != NULL) { - fListener->SetBreakpointEnabledRequested(fBreakpoint, - false); - } else if (fWatchpoint != NULL) { - fListener->SetWatchpointEnabledRequested(fWatchpoint, - false); - } - } - break; case MSG_CLEAR_BREAKPOINT: - if (fListener != NULL) { - if (fBreakpoint != NULL) { - fListener->ClearBreakpointRequested(fBreakpoint); - } else if (fWatchpoint != NULL) { - fListener->ClearWatchpointRequested(fWatchpoint); - } - } + _HandleBreakpointAction(message->what); break; - default: + BGroupView::MessageReceived(message); break; } @@ -157,6 +105,7 @@ BreakpointsView::MessageReceived(BMessage* message) void BreakpointsView::AttachedToWindow() { + fConfigureExceptionsButton->SetTarget(Window()); fToggleBreakpointButton->SetTarget(this); fRemoveBreakpointButton->SetTarget(this); } @@ -187,33 +136,31 @@ BreakpointsView::SaveSettings(BMessage& settings) void -BreakpointsView::BreakpointSelectionChanged(UserBreakpoint* breakpoint) +BreakpointsView::BreakpointSelectionChanged(BreakpointProxyList& proxies) { if (fListener != NULL) - fListener->BreakpointSelectionChanged(breakpoint); -} + fListener->BreakpointSelectionChanged(proxies); - -void -BreakpointsView::WatchpointSelectionChanged(Watchpoint* watchpoint) -{ - if (fListener != NULL) - fListener->WatchpointSelectionChanged(watchpoint); + _SetSelection(proxies); } void BreakpointsView::_Init() { - BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0.0f) - .Add(fListView = BreakpointListView::Create(fTeam, this)) - .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) + .Add(fListView = BreakpointListView::Create(fTeam, this, this)) + .AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING) .SetInsets(B_USE_SMALL_SPACING) - .Add(fToggleBreakpointButton = new BButton("Toggle")) - .Add(fRemoveBreakpointButton = new BButton("Remove")) .AddGlue() + .Add(fConfigureExceptionsButton = new BButton( + "Configure break conditions" B_UTF8_ELLIPSIS)) + .Add(fRemoveBreakpointButton = new BButton("Remove")) + .Add(fToggleBreakpointButton = new BButton("Toggle")) .End(); + fConfigureExceptionsButton->SetMessage( + new BMessage(MSG_SHOW_BREAK_CONDITION_CONFIG_WINDOW)); fToggleBreakpointButton->SetMessage(new BMessage(MSG_ENABLE_BREAKPOINT)); fRemoveBreakpointButton->SetMessage(new BMessage(MSG_CLEAR_BREAKPOINT)); @@ -226,19 +173,44 @@ BreakpointsView::_UpdateButtons() { AutoLocker teamLocker(fTeam); - bool enabled = false; + bool hasEnabled = false; + bool hasDisabled = false; bool valid = false; - if (fBreakpoint != NULL && fBreakpoint->IsValid()) { - valid = true; - enabled = fBreakpoint->IsEnabled(); - } else if (fWatchpoint != NULL) { - valid = true; - enabled = fWatchpoint->IsEnabled(); + for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) { + BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i); + switch (proxy->Type()) { + case BREAKPOINT_PROXY_TYPE_BREAKPOINT: + { + UserBreakpoint* breakpoint = proxy->GetBreakpoint(); + if (breakpoint->IsValid()) { + valid = true; + if (breakpoint->IsEnabled()) + hasEnabled = true; + else + hasDisabled = true; + } + break; + } + case BREAKPOINT_PROXY_TYPE_WATCHPOINT: + { + Watchpoint* watchpoint = proxy->GetWatchpoint(); + valid = true; + if (watchpoint->IsEnabled()) + hasEnabled = true; + else + hasDisabled = true; + break; + } + default: + break; + } } if (valid) { - if (enabled) { + // if we have at least one disabled breakpoint in the + // selection, we leave the button as an Enable button + if (hasEnabled && !hasDisabled) { fToggleBreakpointButton->SetLabel("Disable"); fToggleBreakpointButton->SetMessage( new BMessage(MSG_DISABLE_BREAKPOINT)); @@ -258,6 +230,56 @@ BreakpointsView::_UpdateButtons() } +void +BreakpointsView::_SetSelection(BreakpointProxyList& proxies) +{ + for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) + fSelectedBreakpoints.ItemAt(i)->ReleaseReference(); + + fSelectedBreakpoints.MakeEmpty(); + + for (int32 i = 0; i < proxies.CountItems(); i++) { + BreakpointProxy* proxy = proxies.ItemAt(i); + if (!fSelectedBreakpoints.AddItem(proxy)) + return; + proxy->AcquireReference(); + } + + _UpdateButtons(); +} + + +void +BreakpointsView::_HandleBreakpointAction(uint32 action) +{ + if (fListener == NULL) + return; + + for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) { + BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i); + if (proxy->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) { + UserBreakpoint* breakpoint = proxy->GetBreakpoint(); + if (action == MSG_ENABLE_BREAKPOINT && !breakpoint->IsEnabled()) + fListener->SetBreakpointEnabledRequested(breakpoint, true); + else if (action == MSG_DISABLE_BREAKPOINT + && breakpoint->IsEnabled()) { + fListener->SetBreakpointEnabledRequested(breakpoint, false); + } else if (action == MSG_CLEAR_BREAKPOINT) + fListener->ClearBreakpointRequested(breakpoint); + } else { + Watchpoint* watchpoint = proxy->GetWatchpoint(); + if (action == MSG_ENABLE_BREAKPOINT && !watchpoint->IsEnabled()) + fListener->SetWatchpointEnabledRequested(watchpoint, true); + else if (action == MSG_DISABLE_BREAKPOINT + && watchpoint->IsEnabled()) { + fListener->SetWatchpointEnabledRequested(watchpoint, false); + } else if (action == MSG_CLEAR_BREAKPOINT) + fListener->ClearWatchpointRequested(watchpoint); + } + } +} + + // #pragma mark - Listener diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.h b/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.h index 02bef310b6..ea10f93d69 100644 --- a/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.h +++ b/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.h @@ -12,6 +12,7 @@ class BButton; +class BCheckBox; class BreakpointsView : public BGroupView, @@ -28,9 +29,6 @@ public: void UnsetListener(); - void SetBreakpoint(UserBreakpoint* breakpoint, - Watchpoint* watchpoint); - void UserBreakpointChanged( UserBreakpoint* breakpoint); void WatchpointChanged( @@ -45,19 +43,19 @@ public: private: // BreakpointListView::Listener virtual void BreakpointSelectionChanged( - UserBreakpoint* breakpoint); - virtual void WatchpointSelectionChanged( - Watchpoint* watchpoint); + BreakpointProxyList& proxies); void _Init(); void _UpdateButtons(); + void _SetSelection(BreakpointProxyList& proxies); + void _HandleBreakpointAction(uint32 action); private: Team* fTeam; - UserBreakpoint* fBreakpoint; - Watchpoint* fWatchpoint; BreakpointListView* fListView; + BreakpointProxyList fSelectedBreakpoints; + BButton* fConfigureExceptionsButton; BButton* fToggleBreakpointButton; BButton* fRemoveBreakpointButton; Listener* fListener; @@ -70,15 +68,13 @@ public: virtual ~Listener(); virtual void BreakpointSelectionChanged( - UserBreakpoint* breakpoint) = 0; + BreakpointProxyList& proxies) = 0; virtual void SetBreakpointEnabledRequested( UserBreakpoint* breakpoint, bool enabled) = 0; virtual void ClearBreakpointRequested( UserBreakpoint* breakpoint) = 0; - virtual void WatchpointSelectionChanged( - Watchpoint* Watchpoint) = 0; virtual void SetWatchpointEnabledRequested( Watchpoint* breakpoint, bool enabled) = 0; diff --git a/src/apps/debugger/user_interface/gui/team_window/ConsoleOutputView.cpp b/src/apps/debugger/user_interface/gui/team_window/ConsoleOutputView.cpp new file mode 100644 index 0000000000..cc5876fa24 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/team_window/ConsoleOutputView.cpp @@ -0,0 +1,168 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "ConsoleOutputView.h" + +#include + +#include +#include +#include +#include +#include +#include + + +enum { + MSG_CLEAR_OUTPUT = 'clou' +}; + + +// #pragma mark - ConsoleOutputView + + +ConsoleOutputView::ConsoleOutputView() + : + BGroupView(B_VERTICAL, 0.0f), + fStdoutEnabled(NULL), + fStderrEnabled(NULL), + fConsoleOutput(NULL), + fClearButton(NULL) +{ + SetName("ConsoleOutput"); +} + + +ConsoleOutputView::~ConsoleOutputView() +{ +} + + +/*static*/ ConsoleOutputView* +ConsoleOutputView::Create() +{ + ConsoleOutputView* self = new ConsoleOutputView(); + + try { + self->_Init(); + } catch (...) { + delete self; + throw; + } + + return self; +} + + +void +ConsoleOutputView::ConsoleOutputReceived(int32 fd, const BString& output) +{ + if (fd == 1 && fStdoutEnabled->Value() != B_CONTROL_ON) + return; + else if (fd == 2 && fStderrEnabled->Value() != B_CONTROL_ON) + return; + + text_run_array run; + run.count = 1; + run.runs[0].font = be_fixed_font; + run.runs[0].offset = 0; + run.runs[0].color.red = fd == 1 ? 0 : 192; + run.runs[0].color.green = 0; + run.runs[0].color.blue = 0; + run.runs[0].color.alpha = 255; + + bool autoScroll = false; + BScrollBar* scroller = fConsoleOutput->ScrollBar(B_VERTICAL); + float min, max; + scroller->GetRange(&min, &max); + if (min == max || scroller->Value() == max) + autoScroll = true; + + fConsoleOutput->Insert(fConsoleOutput->TextLength(), output.String(), + output.Length(), &run); + if (autoScroll) { + scroller->GetRange(&min, &max); + fConsoleOutput->ScrollTo(0.0, max); + } +} + + +void +ConsoleOutputView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_CLEAR_OUTPUT: + { + fConsoleOutput->SetText(""); + break; + } + default: + BGroupView::MessageReceived(message); + break; + } +} + + +void +ConsoleOutputView::AttachedToWindow() +{ + BGroupView::AttachedToWindow(); + + fStdoutEnabled->SetValue(B_CONTROL_ON); + fStderrEnabled->SetValue(B_CONTROL_ON); + fClearButton->SetTarget(this); +} + + +void +ConsoleOutputView::LoadSettings(const BMessage& settings) +{ + fStdoutEnabled->SetValue(settings.GetBool("showStdout", true) + ? B_CONTROL_ON : B_CONTROL_OFF); + fStderrEnabled->SetValue(settings.GetBool("showStderr", true) + ? B_CONTROL_ON : B_CONTROL_OFF); +} + + +status_t +ConsoleOutputView::SaveSettings(BMessage& settings) +{ + bool value = fStdoutEnabled->Value() == B_CONTROL_ON; + if (settings.AddBool("showStdout", value) != B_OK) + return B_NO_MEMORY; + + value = fStderrEnabled->Value() == B_CONTROL_ON; + if (settings.AddBool("showStderr", value) != B_OK) + return B_NO_MEMORY; + + return B_OK; +} + + +void +ConsoleOutputView::_Init() +{ + BScrollView* consoleScrollView; + + BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0.0f) + .Add(consoleScrollView = new BScrollView("console scroll", NULL, 0, + true, true), 3.0f) + .AddGroup(B_VERTICAL, 0.0f) + .SetInsets(B_USE_SMALL_SPACING) + .Add(fStdoutEnabled = new BCheckBox("Stdout")) + .Add(fStderrEnabled = new BCheckBox("Stderr")) + .Add(fClearButton = new BButton("Clear")) + .AddGlue() + .End() + .End(); + + consoleScrollView->SetTarget(fConsoleOutput = new BTextView("Console")); + + fClearButton->SetMessage(new BMessage(MSG_CLEAR_OUTPUT)); + fConsoleOutput->MakeEditable(false); + fConsoleOutput->SetStylable(true); + fConsoleOutput->SetDoesUndo(false); +} diff --git a/src/apps/debugger/user_interface/gui/team_window/ConsoleOutputView.h b/src/apps/debugger/user_interface/gui/team_window/ConsoleOutputView.h new file mode 100644 index 0000000000..5413323c66 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/team_window/ConsoleOutputView.h @@ -0,0 +1,46 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef CONSOLE_OUTPUT_VIEW_H_ +#define CONSOLE_OUTPUT_VIEW_H_ + + +#include + + +class BButton; +class BCheckBox; +class BTextView; + + +class ConsoleOutputView : public BGroupView { +public: + ConsoleOutputView(); + ~ConsoleOutputView(); + + static ConsoleOutputView* Create(); + // throws + + void ConsoleOutputReceived( + int32 fd, const BString& output); + + virtual void MessageReceived(BMessage* message); + virtual void AttachedToWindow(); + + void LoadSettings(const BMessage& settings); + status_t SaveSettings(BMessage& settings); + +private: + void _Init(); + +private: + BCheckBox* fStdoutEnabled; + BCheckBox* fStderrEnabled; + BTextView* fConsoleOutput; + BButton* fClearButton; +}; + + + +#endif // CONSOLE_OUTPUT_VIEW_H diff --git a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp index 017c9e436b..45d3b8b174 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp @@ -8,10 +8,16 @@ #include -#include #include +#include + +#include +#include +#include +#include #include +#include #include "table/TableColumns.h" @@ -23,6 +29,15 @@ #include "Tracing.h" +static const uint32 MSG_FUNCTION_FILTER_CHANGED = 'mffc'; +static const uint32 MSG_FUNCTION_TYPING_TIMEOUT = 'mftt'; + +static const uint32 kKeypressTimeout = 250000; + +// from ColumnTypes.cpp +static const float kTextMargin = 8.0; + + // #pragma mark - SourcePathComponentNode @@ -35,7 +50,9 @@ public: fParent(parent), fComponentName(componentName), fSourceFile(sourceFile), - fFunction(function) + fFunction(function), + fFilterMatch(), + fHasMatchingChild(false) { if (fSourceFile != NULL) fSourceFile->AcquireReference(); @@ -122,6 +139,26 @@ public: return true; } + const RegExp::MatchResult& FilterMatch() const + { + return fFilterMatch; + } + + void SetFilterMatch(const RegExp::MatchResult& match) + { + fFilterMatch = match; + } + + bool HasMatchingChild() const + { + return fHasMatchingChild; + } + + void SetHasMatchingChild() + { + fHasMatchingChild = true; + } + private: friend class ImageFunctionsView::FunctionsTableModel; @@ -146,6 +183,76 @@ private: LocatableFile* fSourceFile; FunctionInstance* fFunction; ChildPathComponentList fChildPathComponents; + RegExp::MatchResult fFilterMatch; + bool fHasMatchingChild; +}; + + +// #pragma mark - HighlightingTableColumn + + +class ImageFunctionsView::HighlightingTableColumn : public StringTableColumn { +public: + HighlightingTableColumn(int32 modelIndex, const char* title, float width, + float minWidth, float maxWidth, uint32 truncate, + alignment align = B_ALIGN_LEFT) + : + StringTableColumn(modelIndex, title, width, minWidth, maxWidth, + truncate, align), + fHasFilter(false) + { + } + + void SetHasFilter(bool hasFilter) + { + fHasFilter = hasFilter; + } + + virtual void DrawValue(const BVariant& value, BRect rect, + BView* targetView) + { + StringTableColumn::DrawValue(value, rect, targetView); + + if (fHasFilter) { + // TODO: handle this case as well + if (fField.HasClippedString()) + return; + + const SourcePathComponentNode* node + = (const SourcePathComponentNode*)value.ToPointer(); + + const RegExp::MatchResult& match = node->FilterMatch(); + if (!match.HasMatched()) + return; + + targetView->PushState(); + BRect fillRect(rect); + fillRect.left += kTextMargin + targetView->StringWidth( + fField.String(), match.StartOffset()); + float filterWidth = targetView->StringWidth(fField.String() + + match.StartOffset(), match.EndOffset() + - match.StartOffset()); + fillRect.right = fillRect.left + filterWidth; + targetView->SetLowColor(255, 255, 0, 255); + targetView->SetDrawingMode(B_OP_MIN); + targetView->FillRect(fillRect, B_SOLID_LOW); + targetView->PopState(); + } + } + + virtual BField* PrepareField(const BVariant& value) const + { + const SourcePathComponentNode* node + = (const SourcePathComponentNode*)value.ToPointer(); + + BVariant tempValue(node->ComponentName(), B_VARIANT_DONT_COPY_DATA); + return StringTableColumn::PrepareField(tempValue); + + } + + +private: + bool fHasFilter; }; @@ -169,10 +276,9 @@ public: void SetImageDebugInfo(ImageDebugInfo* imageDebugInfo) { // unset old functions + int32 count = fChildPathComponents.CountItems(); if (fImageDebugInfo != NULL) { - NotifyNodesRemoved(TreeTablePath(), 0, - fChildPathComponents.CountItems()); - for (int32 i = 0; i < fChildPathComponents.CountItems(); i++) + for (int32 i = 0; i < count; i++) fChildPathComponents.ItemAt(i)->ReleaseReference(); fChildPathComponents.MakeEmpty(); @@ -182,49 +288,74 @@ public: fImageDebugInfo = imageDebugInfo; // set new functions - if (fImageDebugInfo == NULL || fImageDebugInfo->CountFunctions() == 0) + if (fImageDebugInfo == NULL || fImageDebugInfo->CountFunctions() + == 0) { + NotifyNodesRemoved(TreeTablePath(), 0, count); return; - - // create an array with the functions - int32 functionCount = fImageDebugInfo->CountFunctions(); - FunctionInstance** functions - = new(std::nothrow) FunctionInstance*[functionCount]; - if (functions == NULL) - return; - ArrayDeleter functionsDeleter(functions); - - for (int32 i = 0; i < functionCount; i++) - functions[i] = fImageDebugInfo->FunctionAt(i); - - // sort them - std::sort(functions, functions + functionCount, &_FunctionLess); - - // eliminate duplicate function instances - if (functionCount > 0) { - Function* previousFunction = functions[0]->GetFunction(); - int32 removed = 0; - for (int32 i = 1; i < functionCount; i++) { - if (functions[i]->GetFunction() == previousFunction) { - removed++; - } else { - functions[i - removed] = functions[i]; - previousFunction = functions[i]->GetFunction(); - } - } - - functionCount -= removed; - // The array might now be too large, but we can live with that. } + std::set functionAddresses; + SourcePathComponentNode* sourcelessNode = new(std::nothrow) SourcePathComponentNode(NULL, "", NULL, NULL); BReference sourceNodeRef( sourcelessNode, true); - + LocatableFile* currentFile = NULL; + BStringList pathComponents; + bool applyFilter = !fFilterString.IsEmpty() + && fCurrentFilter.IsValid(); + int32 functionCount = fImageDebugInfo->CountFunctions(); for (int32 i = 0; i < functionCount; i++) { - if (!_BuildFunctionSourcePath(functions[i], sourcelessNode)) + FunctionInstance* instance = fImageDebugInfo->FunctionAt(i); + target_addr_t address = instance->Address(); + if (functionAddresses.find(address) != functionAddresses.end()) + continue; + else { + try { + functionAddresses.insert(address); + } catch (...) { + return; + } + } + + LocatableFile* sourceFile = instance->SourceFile(); + BString sourcePath; + if (sourceFile != NULL) + sourceFile->GetPath(sourcePath); + + RegExp::MatchResult pathMatch; + RegExp::MatchResult functionMatch; + if (applyFilter && !_FilterFunction(instance, sourcePath, + pathMatch, functionMatch)) { + continue; + } + + if (sourceFile == NULL) { + if (!_AddFunctionNode(sourcelessNode, instance, NULL, + functionMatch)) { + return; + } + continue; + } + + if (sourceFile != currentFile) { + currentFile = sourceFile; + pathComponents.MakeEmpty(); + if (applyFilter) { + pathComponents.Add(sourcePath); + } else { + if (!_GetSourcePathComponents(currentFile, + pathComponents)) { + return; + } + } + } + + if (!_AddFunctionByPath(pathComponents, instance, currentFile, + pathMatch, functionMatch)) { return; + } } if (sourcelessNode->CountChildren() != 0) { @@ -235,8 +366,7 @@ public: } } - NotifyNodesAdded(TreeTablePath(), 0, - fChildPathComponents.CountItems()); + NotifyTableModelReset(); } virtual int32 CountColumns() const @@ -275,11 +405,21 @@ public: SourcePathComponentNode* node = (SourcePathComponentNode*)object; - value.SetTo(node->ComponentName(), B_VARIANT_DONT_COPY_DATA); + value.SetTo(node); return true; } + bool HasMatchingChildAt(void* parent, int32 index) const + { + SourcePathComponentNode* node + = (SourcePathComponentNode*)ChildAt(parent, index); + if (node != NULL) + return node->HasMatchingChild(); + + return false; + } + bool GetFunctionPath(FunctionInstance* function, TreeTablePath& _path) { if (function == NULL) @@ -292,30 +432,20 @@ public: node = fSourcelessNode; _path.AddComponent(fChildPathComponents.IndexOf(node)); } else { - BString sourcePath; - sourceFile->GetPath(sourcePath); - - if (sourcePath.IsEmpty()) + BStringList pathComponents; + if (!_GetSourcePathComponents(sourceFile, pathComponents)) return false; - BString searchPath; - while (!sourcePath.IsEmpty()) { - if (sourcePath[0] == '/') - sourcePath.Remove(0, 1); - int32 separatorIndex = sourcePath.FindFirst('/'); - if (separatorIndex == -1) { - searchPath = sourcePath; - sourcePath.Truncate(0); - } else - sourcePath.MoveInto(searchPath, 0, separatorIndex); + for (int32 i = 0; i < pathComponents.CountStrings(); i++) { + BString component = pathComponents.StringAt(i); if (node == NULL) { childIndex = fChildPathComponents.BinarySearchIndexByKey( - searchPath, + component, &SourcePathComponentNode::CompareByComponentName); node = fChildPathComponents.ItemAt(childIndex); } else { - childIndex = node->FindChildIndexByName(searchPath); + childIndex = node->FindChildIndexByName(component); node = node->ChildAt(childIndex); } @@ -358,70 +488,98 @@ public: return false; } -private: - bool _BuildFunctionSourcePath(FunctionInstance* function, - SourcePathComponentNode* sourcelessNode) + void SetFilter(const char* filter) { - LocatableFile* sourceFile = function->SourceFile(); - if (sourceFile == NULL) - return _AddFunctionNode(sourcelessNode, function, NULL); + fFilterString = filter; + if (fFilterString.IsEmpty() + || fCurrentFilter.SetPattern(filter, RegExp::PATTERN_TYPE_WILDCARD, + false)) { + SetImageDebugInfo(fImageDebugInfo); + } + } +private: + bool _GetSourcePathComponents(LocatableFile* currentFile, + BStringList& pathComponents) + { BString sourcePath; - sourceFile->GetPath(sourcePath); + currentFile->GetPath(sourcePath); if (sourcePath.IsEmpty()) return false; - return _AddNextPathComponent(NULL, sourcePath, function, sourceFile); - } + int32 startIndex = 0; + if (sourcePath[0] == '/') + startIndex = 1; - bool _AddNextPathComponent(SourcePathComponentNode* parent, - BString& childPath, FunctionInstance* function, LocatableFile* file) - { - if (childPath[0] == '/') - childPath.Remove(0, 1); + while (startIndex < sourcePath.Length()) { + int32 searchIndex = sourcePath.FindFirst('/', startIndex); + BString data; + if (searchIndex < 0) + searchIndex = sourcePath.Length(); - BString pathComponent; - int32 pathSeparatorIndex = childPath.FindFirst('/'); - if (pathSeparatorIndex == -1) - pathComponent = childPath; - else - childPath.MoveInto(pathComponent, 0, pathSeparatorIndex); - - SourcePathComponentNode* currentNode = NULL; - if (parent == NULL) { - currentNode = fChildPathComponents.BinarySearchByKey(pathComponent, - SourcePathComponentNode::CompareByComponentName); - } else - currentNode = parent->FindChildByName(pathComponent); - - if (currentNode == NULL) { - currentNode = new(std::nothrow) SourcePathComponentNode(parent, - pathComponent, NULL, NULL); - if (currentNode == NULL) + sourcePath.CopyInto(data, startIndex, searchIndex - startIndex); + if (!pathComponents.Add(data)) return false; - BReference nodeReference(currentNode, - true); - if (parent != NULL) { - if (!parent->AddChild(currentNode)) - return false; - } else { - if (!fChildPathComponents.BinaryInsert(currentNode, - &SourcePathComponentNode::CompareComponents)) { - return false; - } - nodeReference.Detach(); - } + startIndex = searchIndex + 1; } - if (pathSeparatorIndex == -1) - return _AddFunctionNode(currentNode, function, file); + return true; + } - return _AddNextPathComponent(currentNode, childPath, function, file); + bool _AddFunctionByPath(const BStringList& pathComponents, + FunctionInstance* function, LocatableFile* file, + RegExp::MatchResult& pathMatch, RegExp::MatchResult& functionMatch) + { + SourcePathComponentNode* parentNode = NULL; + SourcePathComponentNode* currentNode = NULL; + for (int32 i = 0; i < pathComponents.CountStrings(); i++) { + const BString pathComponent = pathComponents.StringAt(i); + if (parentNode == NULL) { + currentNode = fChildPathComponents.BinarySearchByKey( + pathComponent, + SourcePathComponentNode::CompareByComponentName); + } else + currentNode = parentNode->FindChildByName(pathComponent); + + if (currentNode == NULL) { + currentNode = new(std::nothrow) SourcePathComponentNode( + parentNode, pathComponent, NULL, NULL); + if (currentNode == NULL) + return false; + + if (pathComponents.CountStrings() == 1) + currentNode->SetFilterMatch(pathMatch); + + BReference nodeReference(currentNode, + true); + if (parentNode != NULL) { + if (!parentNode->AddChild(currentNode)) + return false; + } else { + if (!fChildPathComponents.BinaryInsert(currentNode, + &SourcePathComponentNode::CompareComponents)) { + return false; + } + + nodeReference.Detach(); + } + } + + if (functionMatch.HasMatched()) + currentNode->SetHasMatchingChild(); + + parentNode = currentNode; + + } + + return _AddFunctionNode(currentNode, function, file, + functionMatch); } bool _AddFunctionNode(SourcePathComponentNode* parent, - FunctionInstance* function, LocatableFile* file) + FunctionInstance* function, LocatableFile* file, + RegExp::MatchResult& match) { SourcePathComponentNode* functionNode = new(std::nothrow) SourcePathComponentNode(parent, function->PrettyName(), file, @@ -430,6 +588,8 @@ private: if (functionNode == NULL) return B_NO_MEMORY; + functionNode->SetFilterMatch(match); + BReference nodeReference(functionNode, true); if (!parent->AddChild(functionNode)) return false; @@ -437,37 +597,15 @@ private: return true; } - static int _CompareSourceFileNames(LocatableFile* a, LocatableFile* b) + bool _FilterFunction(FunctionInstance* instance, const BString& sourcePath, + RegExp::MatchResult& pathMatch, RegExp::MatchResult& functionMatch) { - if (a == b) - return 0; + functionMatch = fCurrentFilter.Match(instance->PrettyName()); + pathMatch = fCurrentFilter.Match(sourcePath.String()); - if (a == NULL) - return 1; - if (b == NULL) - return -1; - - BString pathA; - a->GetPath(pathA); - - BString pathB; - b->GetPath(pathB); - - return pathA.Compare(pathB); + return functionMatch.HasMatched() || pathMatch.HasMatched(); } - static bool _FunctionLess(const FunctionInstance* a, - const FunctionInstance* b) - { - // compare source file name first - int compared = _CompareSourceFileNames(a->SourceFile(), - b->SourceFile()); - if (compared != 0) - return compared < 0; - - // source file names are equal -- compare the function names - return strcasecmp(a->PrettyName(), b->PrettyName()) < 0; - } private: typedef BObjectList ChildPathComponentList; @@ -476,6 +614,8 @@ private: ImageDebugInfo* fImageDebugInfo; ChildPathComponentList fChildPathComponents; SourcePathComponentNode* fSourcelessNode; + BString fFilterString; + RegExp fCurrentFilter; }; @@ -486,9 +626,12 @@ ImageFunctionsView::ImageFunctionsView(Listener* listener) : BGroupView(B_VERTICAL), fImageDebugInfo(NULL), + fFilterField(NULL), fFunctionsTable(NULL), fFunctionsTableModel(NULL), - fListener(listener) + fListener(listener), + fHighlightingColumn(NULL), + fLastFilterKeypress(0) { SetName("Functions"); } @@ -575,6 +718,46 @@ ImageFunctionsView::SetFunction(FunctionInstance* function) } +void +ImageFunctionsView::AttachedToWindow() +{ + BView::AttachedToWindow(); + + fFilterField->SetTarget(this); +} + + +void +ImageFunctionsView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_FUNCTION_FILTER_CHANGED: + { + fLastFilterKeypress = system_time(); + BMessage keypressMessage(MSG_FUNCTION_TYPING_TIMEOUT); + BMessageRunner::StartSending(BMessenger(this), &keypressMessage, + kKeypressTimeout, 1); + break; + } + + case MSG_FUNCTION_TYPING_TIMEOUT: + { + if (system_time() - fLastFilterKeypress >= kKeypressTimeout) { + fFunctionsTableModel->SetFilter(fFilterField->Text()); + fHighlightingColumn->SetHasFilter( + fFilterField->TextView()->TextLength() > 0); + _ExpandFilteredNodes(); + } + break; + } + + default: + BView::MessageReceived(message); + break; + } +} + + void ImageFunctionsView::LoadSettings(const BMessage& settings) { @@ -622,11 +805,17 @@ ImageFunctionsView::_Init() { fFunctionsTable = new TreeTable("functions", 0, B_FANCY_BORDER); AddChild(fFunctionsTable->ToView()); + AddChild(fFilterField = new BTextControl("filtertext", "Filter:", + NULL, NULL)); + + fFilterField->SetModificationMessage(new BMessage( + MSG_FUNCTION_FILTER_CHANGED)); fFunctionsTable->SetSortingEnabled(false); // columns - fFunctionsTable->AddColumn(new StringTableColumn(0, "File/Function", 300, - 100, 1000, B_TRUNCATE_BEGINNING, B_ALIGN_LEFT)); + fFunctionsTable->AddColumn(fHighlightingColumn + = new HighlightingTableColumn(0, "File/Function", 300, 100, 1000, + B_TRUNCATE_BEGINNING, B_ALIGN_LEFT)); fFunctionsTableModel = new FunctionsTableModel(); fFunctionsTable->SetTreeTableModel(fFunctionsTableModel); @@ -636,6 +825,29 @@ ImageFunctionsView::_Init() } +void +ImageFunctionsView::_ExpandFilteredNodes() +{ + if (fFilterField->TextView()->TextLength() == 0) + return; + + for (int32 i = 0; i < fFunctionsTableModel->CountChildren( + fFunctionsTableModel); i++) { + // only expand nodes if the match actually hit a function, + // and not just the containing path. + if (fFunctionsTableModel->CountChildren(fFunctionsTableModel) == 1 + || fFunctionsTableModel->HasMatchingChildAt(fFunctionsTableModel, + i)) { + TreeTablePath path; + path.AddComponent(i); + fFunctionsTable->SetNodeExpanded(path, true, true); + } + } + + fFunctionsTable->ResizeAllColumnsToPreferred(); +} + + // #pragma mark - Listener diff --git a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h index 55fb9594ac..f5801acffb 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h +++ b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h @@ -12,6 +12,7 @@ #include "Team.h" +class BTextControl; class FunctionInstance; @@ -31,12 +32,15 @@ public: void SetImageDebugInfo( ImageDebugInfo* imageDebugInfo); void SetFunction(FunctionInstance* function); + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); void LoadSettings(const BMessage& settings); status_t SaveSettings(BMessage& settings); private: class FunctionsTableModel; + class HighlightingTableColumn; class SourcePathComponentNode; private: @@ -45,11 +49,16 @@ private: void _Init(); + void _ExpandFilteredNodes(); + private: ImageDebugInfo* fImageDebugInfo; + BTextControl* fFilterField; TreeTable* fFunctionsTable; FunctionsTableModel* fFunctionsTableModel; Listener* fListener; + HighlightingTableColumn* fHighlightingColumn; + bigtime_t fLastFilterKeypress; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/SourceView.cpp b/src/apps/debugger/user_interface/gui/team_window/SourceView.cpp index fad29e172c..c9249d94c0 100644 --- a/src/apps/debugger/user_interface/gui/team_window/SourceView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/SourceView.cpp @@ -14,11 +14,15 @@ #include #include +#include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -27,6 +31,7 @@ #include #include +#include "AutoDeleter.h" #include "Breakpoint.h" #include "DisassembledCode.h" #include "Function.h" @@ -53,6 +58,11 @@ static const char* kDisableBreakpointMessage = "Click to disable breakpoint at " static const char* kEnableBreakpointMessage = "Click to enable breakpoint at " "line %" B_PRId32 "."; +static const uint32 MSG_OPEN_SOURCE_FILE = 'mosf'; +static const uint32 MSG_SWITCH_DISASSEMBLY_STATE = 'msds'; + +static const char* kTrackerSignature = "application/x-vnd.Be-TRAK"; + class SourceView::BaseView : public BView { public: @@ -174,6 +184,7 @@ private: MarkerManager* fMarkerManager; StackTrace* fStackTrace; StackFrame* fStackFrame; + rgb_color fBackgroundColor; rgb_color fBreakpointOptionMarker; }; @@ -197,6 +208,8 @@ struct SourceView::MarkerManager::InstructionPointerMarker : Marker { virtual void Draw(BView* view, BRect rect); + bool IsCurrentIP() const { return fIsCurrentIP; } + private: void _DrawArrow(BView* view, BPoint tip, BSize size, BSize base, const rgb_color& color, @@ -311,6 +324,19 @@ private: void _ScrollToTop(); void _ScrollToBottom(); + bool _AddGeneralActions(BPopUpMenu* menu, + int32 line); + bool _AddFlowControlActions(BPopUpMenu* menu, + int32 line); + + bool _AddGeneralActionItem(BPopUpMenu* menu, + const char* text, BMessage* message) const; + // takes ownership of message + // regardless of outcome + bool _AddFlowControlActionItem(BPopUpMenu* menu, + const char* text, uint32 what, + target_addr_t address) const; + private: float fMaxLineWidth; @@ -664,6 +690,8 @@ SourceView::MarkerManager::_UpdateBreakpointMarkers() for (int32 i = 0; UserBreakpoint* breakpoint = breakpoints.ItemAt(i); i++) { + if (breakpoint->IsHidden()) + continue; UserBreakpointInstance* breakpointInstance = breakpoint->InstanceAt(0); FunctionInstance* functionInstance; @@ -810,9 +838,9 @@ SourceView::MarkerView::MarkerView(SourceView* sourceView, Team* team, fStackFrame(NULL) { rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR); - fBreakpointOptionMarker = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), - B_DARKEN_1_TINT); - SetViewColor(tint_color(background, B_LIGHTEN_2_TINT)); + fBreakpointOptionMarker = tint_color(background, B_DARKEN_1_TINT); + fBackgroundColor = tint_color(background, B_LIGHTEN_2_TINT); + SetViewColor(B_TRANSPARENT_COLOR); } @@ -865,8 +893,11 @@ SourceView::MarkerView::MaxSize() void SourceView::MarkerView::Draw(BRect updateRect) { - if (fSourceCode == NULL) + SetLowColor(fBackgroundColor); + if (fSourceCode == NULL) { + FillRect(updateRect, B_SOLID_LOW); return; + } // get the lines intersecting with the update rect int32 minLine, maxLine; @@ -887,6 +918,7 @@ SourceView::MarkerView::Draw(BRect updateRect) bool drawBreakpointOptionMarker = true; SourceView::MarkerManager::Marker* marker; + FillRect(LineRect(line), B_SOLID_LOW); while ((marker = markers.ItemAt(markerIndex)) != NULL && marker->Line() == (uint32)line) { marker->Draw(this, LineRect(line)); @@ -908,6 +940,13 @@ SourceView::MarkerView::Draw(BRect updateRect) SetHighColor(fBreakpointOptionMarker); FillEllipse(BPoint(width - 8, y), 2, 2); } + + float y = (maxLine + 1) * fFontInfo->lineHeight; + if (y < updateRect.bottom) { + FillRect(BRect(0.0, y, Bounds().right, updateRect.bottom), + B_SOLID_LOW); + } + } @@ -918,18 +957,11 @@ SourceView::MarkerView::MouseDown(BPoint where) return; int32 line = LineAtOffset(where.y); - if (line < 0) - return; - AutoLocker locker(fTeam); Statement* statement; - if (fTeam->GetStatementAtSourceLocation(fSourceCode, - SourceLocation(line), statement) != B_OK) { + if (!fSourceView->GetStatementForLine(line, statement)) return; - } BReference statementReference(statement, true); - if (statement->StartSourceLocation().Line() != line) - return; int32 modifiers; if (Looper()->CurrentMessage()->FindInt32("modifiers", &modifiers) != B_OK) @@ -1025,7 +1057,7 @@ SourceView::TextView::TextView(SourceView* sourceView, MarkerManager* manager, fScrollRunner(NULL), fMarkerManager(manager) { - SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + SetViewColor(B_TRANSPARENT_COLOR); fTextColor = ui_color(B_DOCUMENT_TEXT_COLOR); SetFlags(Flags() | B_NAVIGABLE); } @@ -1065,8 +1097,11 @@ SourceView::TextView::MaxSize() void SourceView::TextView::Draw(BRect updateRect) { - if (fSourceCode == NULL) + if (fSourceCode == NULL) { + SetLowColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + FillRect(updateRect, B_SOLID_LOW); return; + } // get the lines intersecting with the update rect int32 minLine, maxLine; @@ -1078,13 +1113,17 @@ SourceView::TextView::Draw(BRect updateRect) SetHighColor(fTextColor); SetFont(&fFontInfo->font); SourceView::MarkerManager::Marker* marker; + SourceView::MarkerManager::InstructionPointerMarker* ipMarker; int32 markerIndex = 0; + float y; for (int32 i = minLine; i <= maxLine; i++) { - SetLowColor(ViewColor()); - float y = i * fFontInfo->lineHeight; + SetLowColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + y = i * fFontInfo->lineHeight; BString lineString; _FormatLine(fSourceCode->LineAt(i), lineString); + FillRect(BRect(0.0, y, kLeftTextMargin, y + fFontInfo->lineHeight), + B_SOLID_LOW); for (int32 j = markerIndex; j < markers.CountItems(); j++) { marker = markers.ItemAt(j); if (marker->Line() < (uint32)i) { @@ -1092,22 +1131,33 @@ SourceView::TextView::Draw(BRect updateRect) continue; } else if (marker->Line() == (uint32)i) { ++markerIndex; - if (dynamic_cast(marker) != NULL) - SetLowColor(96, 216, 216, 255); - else + ipMarker = dynamic_cast(marker); + if (ipMarker != NULL) { + if (ipMarker->IsCurrentIP()) + SetLowColor(96, 216, 216, 255); + else + SetLowColor(216, 216, 216, 255); + + } else SetLowColor(255, 255, 0, 255); - FillRect(BRect(kLeftTextMargin, y, Bounds().right, - y + fFontInfo->lineHeight), B_SOLID_LOW); break; } else break; } + FillRect(BRect(kLeftTextMargin, y, Bounds().right, + y + fFontInfo->lineHeight - 1), B_SOLID_LOW); DrawString(lineString, BPoint(kLeftTextMargin, y + fFontInfo->fontHeight.ascent)); } + y = (maxLine + 1) * fFontInfo->lineHeight; + if (y < updateRect.bottom) { + FillRect(BRect(0.0, y, Bounds().right, updateRect.bottom), + B_SOLID_LOW); + } + if (fSelectionStart.line != -1 && fSelectionEnd.line != -1) { PushState(); BRegion selectionRegion; @@ -1193,7 +1243,15 @@ SourceView::TextView::MessageReceived(BMessage* message) void SourceView::TextView::MouseDown(BPoint where) { - if (fSourceCode != NULL) { + if (fSourceCode == NULL) + return; + + int32 buttons; + if (Looper()->CurrentMessage()->FindInt32("buttons", &buttons) != B_OK) + buttons = B_PRIMARY_MOUSE_BUTTON; + + + if (buttons == B_PRIMARY_MOUSE_BUTTON) { if (!IsFocus()) MakeFocus(true); fTrackState = kTracking; @@ -1233,6 +1291,39 @@ SourceView::TextView::MouseDown(BPoint where) Invalidate(); SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); } + } else if (buttons == B_SECONDARY_MOUSE_BUTTON) { + int32 line = LineAtOffset(where.y); + if (line < 0) + return; + + ::Team* team = fSourceView->fTeam; + AutoLocker locker(team); + ::Thread* activeThread = fSourceView->fActiveThread; + + if (activeThread == NULL) + return; + else if (activeThread->State() != THREAD_STATE_STOPPED) + return; + + BPopUpMenu* menu = new(std::nothrow) BPopUpMenu(""); + if (menu == NULL) + return; + ObjectDeleter menuDeleter(menu); + + if (!_AddGeneralActions(menu, line)) + return; + + if (!_AddFlowControlActions(menu, line)) + return; + + menuDeleter.Detach(); + + BPoint screenWhere(where); + ConvertToScreen(&screenWhere); + menu->SetTargetForItems(fSourceView); + BRect mouseRect(screenWhere, screenWhere); + mouseRect.InsetBy(-4.0, -4.0); + menu->Go(screenWhere, true, false, mouseRect, true); } } @@ -1688,6 +1779,130 @@ SourceView::TextView::_ScrollToBottom(void) } +bool +SourceView::TextView::_AddGeneralActions(BPopUpMenu* menu, int32 line) +{ + if (fSourceCode == NULL) + return true; + + BMessage* message = NULL; + if (fSourceCode->GetSourceFile() != NULL) { + message = new(std::nothrow) BMessage(MSG_OPEN_SOURCE_FILE); + if (message == NULL) + return false; + message->AddInt32("line", line); + + if (!_AddGeneralActionItem(menu, "Open source file", message)) + return false; + } + + if (fSourceView->fStackFrame == NULL) + return true; + + FunctionInstance* instance = fSourceView->fStackFrame->Function(); + if (instance == NULL) + return true; + + FileSourceCode* code = instance->GetFunction()->GetSourceCode(); + + // if we only have disassembly, this option doesn't apply. + if (code == NULL) + return true; + + // verify that we do in fact know the source file of the function, + // since we can't switch to it if it wasn't found and hasn't been + // located. + BString sourcePath; + code->GetSourceFile()->GetLocatedPath(sourcePath); + if (sourcePath.IsEmpty()) + return true; + + message = new(std::nothrow) BMessage( + MSG_SWITCH_DISASSEMBLY_STATE); + if (message == NULL) + return false; + + if (!_AddGeneralActionItem(menu, dynamic_cast( + fSourceCode) != NULL ? "Show source" : "Show disassembly", + message)) { + return false; + } + + return true; +} + + +bool +SourceView::TextView::_AddFlowControlActions(BPopUpMenu* menu, int32 line) +{ + Statement* statement; + if (!fSourceView->GetStatementForLine(line, statement)) + return true; + + BReference statementReference(statement, true); + target_addr_t address = statement->CoveringAddressRange().Start(); + + if (menu->CountItems() > 0) + menu->AddSeparatorItem(); + + if (!_AddFlowControlActionItem(menu, "Run to cursor", MSG_THREAD_RUN, + address)) { + return false; + } + + if (!_AddFlowControlActionItem(menu, "Set next statement", + MSG_THREAD_SET_ADDRESS, address)) { + return false; + } + + return true; +} + + +bool +SourceView::TextView::_AddGeneralActionItem(BPopUpMenu* menu, const char* text, + BMessage* message) const +{ + ObjectDeleter messageDeleter(message); + + BMenuItem* item = new(std::nothrow) BMenuItem(text, message); + if (item == NULL) + return false; + ObjectDeleter itemDeleter(item); + messageDeleter.Detach(); + + if (!menu->AddItem(item)) + return false; + + itemDeleter.Detach(); + return true; +} + + +bool +SourceView::TextView::_AddFlowControlActionItem(BPopUpMenu* menu, + const char* text, uint32 what, target_addr_t address) const +{ + BMessage* message = new(std::nothrow) BMessage(what); + if (message == NULL) + return false; + ObjectDeleter messageDeleter(message); + + message->AddUInt64("address", address); + BMenuItem* item = new(std::nothrow) BMenuItem(text, message); + if (item == NULL) + return false; + ObjectDeleter itemDeleter(item); + messageDeleter.Detach(); + + if (!menu->AddItem(item)) + return false; + + itemDeleter.Detach(); + return true; +} + + // #pragma mark - SourceView @@ -1695,6 +1910,7 @@ SourceView::SourceView(Team* team, Listener* listener) : BView("source view", 0), fTeam(team), + fActiveThread(NULL), fStackTrace(NULL), fStackFrame(NULL), fSourceCode(NULL), @@ -1713,7 +1929,7 @@ SourceView::SourceView(Team* team, Listener* listener) SourceView::~SourceView() { SetStackFrame(NULL); - SetStackTrace(NULL); + SetStackTrace(NULL, NULL); SetSourceCode(NULL); } @@ -1734,6 +1950,97 @@ SourceView::Create(Team* team, Listener* listener) } +void +SourceView::MessageReceived(BMessage* message) +{ + switch(message->what) { + case MSG_THREAD_RUN: + case MSG_THREAD_SET_ADDRESS: + { + target_addr_t address; + if (message->FindUInt64("address", &address) != B_OK) + break; + fListener->ThreadActionRequested(fActiveThread, message->what, + address); + break; + } + + case MSG_OPEN_SOURCE_FILE: + { + int32 line; + if (message->FindInt32("line", &line) != B_OK) + break; + // be:line is 1-based. + ++line; + if (fSourceCode == NULL) + break; + LocatableFile* file = fSourceCode->GetSourceFile(); + if (file == NULL) + break; + + BString sourcePath; + file->GetLocatedPath(sourcePath); + if (sourcePath.IsEmpty()) + break; + + BPath path(sourcePath); + entry_ref ref; + if (path.InitCheck() != B_OK) + break; + + if (get_ref_for_path(path.Path(), &ref) != B_OK) + break; + + BMessage trackerMessage(B_REFS_RECEIVED); + trackerMessage.AddRef("refs", &ref); + trackerMessage.AddInt32("be:line", line); + + BMessenger messenger(kTrackerSignature); + messenger.SendMessage(&trackerMessage); + break; + } + + case MSG_SWITCH_DISASSEMBLY_STATE: + { + if (fStackFrame == NULL) + break; + + FunctionInstance* instance = fStackFrame->Function(); + if (instance == NULL) + break; + + SourceCode* code = NULL; + if (dynamic_cast(fSourceCode) != NULL) { + if (instance->SourceCodeState() + == FUNCTION_SOURCE_NOT_LOADED) { + fListener->FunctionSourceCodeRequested(instance, true); + break; + } + + code = instance->GetSourceCode(); + } else { + Function* function = instance->GetFunction(); + if (function->SourceCodeState() + == FUNCTION_SOURCE_NOT_LOADED) { + fListener->FunctionSourceCodeRequested(instance, false); + break; + } + + code = function->GetSourceCode(); + } + + if (code != NULL) + SetSourceCode(code); + break; + } + + default: + BView::MessageReceived(message); + break; + } +} + + void SourceView::UnsetListener() { @@ -1742,13 +2049,21 @@ SourceView::UnsetListener() void -SourceView::SetStackTrace(StackTrace* stackTrace) +SourceView::SetStackTrace(StackTrace* stackTrace, Thread* activeThread) { TRACE_GUI("SourceView::SetStackTrace(%p)\n", stackTrace); if (stackTrace == fStackTrace) return; + if (fActiveThread != NULL) + fActiveThread->ReleaseReference(); + + fActiveThread = activeThread; + + if (fActiveThread != NULL) + fActiveThread->AcquireReference(); + if (fStackTrace != NULL) { fMarkerManager->SetStackTrace(NULL); fMarkerView->SetStackTrace(NULL); @@ -1762,13 +2077,13 @@ SourceView::SetStackTrace(StackTrace* stackTrace) fMarkerManager->SetStackTrace(fStackTrace); fMarkerView->SetStackTrace(fStackTrace); - fTextView->Invalidate(); } void SourceView::SetStackFrame(StackFrame* stackFrame) { + TRACE_GUI("SourceView::SetStackFrame(%p)\n", stackFrame); if (stackFrame == fStackFrame) return; @@ -1949,6 +2264,29 @@ SourceView::DoLayout() } +bool +SourceView::GetStatementForLine(int32 line, Statement*& _statement) +{ + if (line < 0) + return false; + + AutoLocker locker(fTeam); + Statement* statement; + if (fTeam->GetStatementAtSourceLocation(fSourceCode, SourceLocation(line), + statement) != B_OK) { + return false; + } + BReference statementReference(statement, true); + if (statement->StartSourceLocation().Line() != line) + return false; + + _statement = statement; + statementReference.Detach(); + + return true; +} + + void SourceView::_Init() { diff --git a/src/apps/debugger/user_interface/gui/team_window/SourceView.h b/src/apps/debugger/user_interface/gui/team_window/SourceView.h index bf12eefb2d..df4132bf6f 100644 --- a/src/apps/debugger/user_interface/gui/team_window/SourceView.h +++ b/src/apps/debugger/user_interface/gui/team_window/SourceView.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef SOURCE_VIEW_H @@ -13,11 +14,13 @@ class Breakpoint; +class FunctionInstance; class SourceCode; class StackFrame; class StackTrace; class Statement; class Team; +class Thread; class UserBreakpoint; @@ -32,9 +35,12 @@ public: static SourceView* Create(Team* team, Listener* listener); // throws + virtual void MessageReceived(BMessage* message); + void UnsetListener(); - void SetStackTrace(StackTrace* stackTrace); + void SetStackTrace(StackTrace* stackTrace, + Thread* thread); void SetStackFrame(StackFrame* stackFrame); void SetSourceCode(SourceCode* sourceCode); @@ -59,12 +65,20 @@ private: class MarkerView; class TextView; + // for gcc2 + friend class TextView; + friend class MarkerView; + struct FontInfo { BFont font; font_height fontHeight; float lineHeight; }; +protected: + bool GetStatementForLine(int32 line, + Statement*& _statement); + private: void _Init(); void _UpdateScrollBars(); @@ -72,6 +86,7 @@ private: private: Team* fTeam; + Thread* fActiveThread; StackTrace* fStackTrace; StackFrame* fStackFrame; SourceCode* fSourceCode; @@ -91,6 +106,11 @@ public: target_addr_t address, bool enabled) = 0; virtual void ClearBreakpointRequested( target_addr_t address) = 0; + virtual void ThreadActionRequested(Thread* thread, + uint32 action, target_addr_t address) = 0; + virtual void FunctionSourceCodeRequested( + FunctionInstance* function, + bool forceDisassembly) = 0; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp index c36ac9b742..bbce26ed50 100644 --- a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -12,6 +12,7 @@ #include #include +#include #include "table/TableColumns.h" @@ -107,6 +108,7 @@ StackTraceView::StackTraceView(Listener* listener) fStackTrace(NULL), fFramesTable(NULL), fFramesTableModel(NULL), + fTraceClearPending(false), fListener(listener) { SetName("Stack Trace"); @@ -147,6 +149,7 @@ StackTraceView::UnsetListener() void StackTraceView::SetStackTrace(StackTrace* stackTrace) { + fTraceClearPending = false; if (stackTrace == fStackTrace) return; @@ -204,10 +207,17 @@ StackTraceView::SaveSettings(BMessage& settings) } +void +StackTraceView::SetStackTraceClearPending() +{ + fTraceClearPending = true; +} + + void StackTraceView::TableSelectionChanged(Table* table) { - if (fListener == NULL) + if (fListener == NULL || fTraceClearPending) return; StackFrame* frame diff --git a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h index 5ce2fbe9bb..01cbdde833 100644 --- a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h +++ b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h @@ -33,6 +33,8 @@ public: void LoadSettings(const BMessage& settings); status_t SaveSettings(BMessage& settings); + void SetStackTraceClearPending(); + private: class FramesTableModel; @@ -46,6 +48,7 @@ private: StackTrace* fStackTrace; Table* fFramesTable; FramesTableModel* fFramesTableModel; + bool fTraceClearPending; Listener* fListener; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index 0f2e594e12..de8cda1b5a 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010-2012, Rene Gollent, rene@gollent.com. + * Copyright 2010-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -29,8 +30,10 @@ #include #include "Breakpoint.h" +#include "ConsoleOutputView.h" #include "CpuState.h" #include "DisassembledCode.h" +#include "BreakConditionConfigWindow.h" #include "FileSourceCode.h" #include "GuiSettingsUtils.h" #include "GuiTeamUiSettings.h" @@ -57,9 +60,10 @@ enum { enum { - MSG_CHOOSE_DEBUG_REPORT_LOCATION = 'ccrl', - MSG_DEBUG_REPORT_SAVED = 'drsa', - MSG_LOCATE_SOURCE_IF_NEEDED = 'lsin' + MSG_CHOOSE_DEBUG_REPORT_LOCATION = 'ccrl', + MSG_DEBUG_REPORT_SAVED = 'drsa', + MSG_LOCATE_SOURCE_IF_NEEDED = 'lsin', + MSG_CLEAR_STACK_TRACE = 'clst' }; @@ -101,6 +105,7 @@ TeamWindow::TeamWindow(::Team* team, UserInterfaceListener* listener) fActiveSourceCode(NULL), fActiveSourceObject(ACTIVE_SOURCE_NONE), fListener(listener), + fTraceUpdateRunner(NULL), fTabView(NULL), fLocalsTabView(NULL), fThreadListView(NULL), @@ -115,6 +120,15 @@ TeamWindow::TeamWindow(::Team* team, UserInterfaceListener* listener) fStepOverButton(NULL), fStepIntoButton(NULL), fStepOutButton(NULL), + fMenuBar(NULL), + fSourcePathView(NULL), + fConsoleOutputView(NULL), + fFunctionSplitView(NULL), + fSourceSplitView(NULL), + fImageSplitView(NULL), + fThreadSplitView(NULL), + fConsoleSplitView(NULL), + fBreakConditionConfigWindow(NULL), fInspectorWindow(NULL), fFilePanel(NULL) { @@ -174,7 +188,7 @@ TeamWindow::DispatchMessage(BMessage* message, BHandler* handler) // Handle function key shortcuts for stepping switch (message->what) { case B_KEY_DOWN: - if (fActiveThread != NULL) { + if (fActiveThread != NULL && fTraceUpdateRunner == NULL) { int32 key; uint32 modifiers; if (message->FindInt32("key", &key) == B_OK @@ -220,6 +234,11 @@ void TeamWindow::MessageReceived(BMessage* message) { switch (message->what) { + case MSG_TEAM_RESTART_REQUESTED: + { + fListener->TeamRestartRequested(); + break; + } case MSG_CHOOSE_DEBUG_REPORT_LOCATION: { try { @@ -257,8 +276,11 @@ TeamWindow::MessageReceived(BMessage* message) BString data; data.SetToFormat("Debug report successfully saved to '%s'", message->FindString("path")); - BAlert *alert = new BAlert("Report saved", data.String(), - "OK"); + BAlert *alert = new(std::nothrow) BAlert("Report saved", + data.String(), "Close"); + if (alert == NULL) + break; + alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); alert->Go(); break; @@ -296,6 +318,28 @@ TeamWindow::MessageReceived(BMessage* message) break; } + case MSG_SHOW_BREAK_CONDITION_CONFIG_WINDOW: + { + if (fBreakConditionConfigWindow) { + fBreakConditionConfigWindow->Activate(true); + } else { + try { + fBreakConditionConfigWindow + = BreakConditionConfigWindow::Create( + fTeam, fListener, this); + if (fBreakConditionConfigWindow != NULL) + fBreakConditionConfigWindow->Show(); + } catch (...) { + // TODO: notify user + } + } + break; + } + case MSG_BREAK_CONDITION_CONFIG_WINDOW_CLOSED: + { + fBreakConditionConfigWindow = NULL; + break; + } case MSG_SHOW_WATCH_VARIABLE_PROMPT: { target_addr_t address; @@ -321,7 +365,9 @@ TeamWindow::MessageReceived(BMessage* message) case B_REFS_RECEIVED: { entry_ref locatedPath; - message->FindRef("refs", &locatedPath); + if (message->FindRef("refs", &locatedPath) != B_OK) + break; + _HandleResolveMissingSourceFile(locatedPath); break; } @@ -330,7 +376,9 @@ TeamWindow::MessageReceived(BMessage* message) if (fActiveFunction != NULL && fActiveFunction->GetFunctionDebugInfo() ->SourceFile() != NULL && fActiveSourceCode != NULL - && fActiveSourceCode->GetSourceFile() == NULL) { + && fActiveSourceCode->GetSourceFile() == NULL + && fActiveFunction->GetFunction()->SourceCodeState() + != FUNCTION_SOURCE_NOT_LOADED) { try { if (fFilePanel == NULL) { fFilePanel = new BFilePanel(B_OPEN_PANEL, @@ -349,12 +397,20 @@ TeamWindow::MessageReceived(BMessage* message) case MSG_THREAD_STEP_OVER: case MSG_THREAD_STEP_INTO: case MSG_THREAD_STEP_OUT: - if (fActiveThread != NULL) { + if (fActiveThread != NULL && fTraceUpdateRunner == NULL) { fListener->ThreadActionRequested(fActiveThread->ID(), message->what); } break; + case MSG_CLEAR_STACK_TRACE: + { + if (fTraceUpdateRunner != NULL) { + _SetActiveStackTrace(NULL); + _UpdateRunButtons(); + } + break; + } case MSG_THREAD_STATE_CHANGED: { int32 threadID; @@ -394,6 +450,18 @@ TeamWindow::MessageReceived(BMessage* message) break; } + case MSG_CONSOLE_OUTPUT_RECEIVED: + { + int32 fd; + BString output; + if (message->FindInt32("fd", &fd) != B_OK + || message->FindString("output", &output) != B_OK) { + break; + } + fConsoleOutputView->ConsoleOutputReceived(fd, output); + break; + } + case MSG_USER_BREAKPOINT_CHANGED: { UserBreakpoint* breakpoint; @@ -470,6 +538,9 @@ TeamWindow::LoadSettings(const GuiTeamUiSettings* settings) if (teamWindowSettings.FindMessage("threadSplit", &archive) == B_OK) GuiSettingsUtils::UnarchiveSplitView(archive, fThreadSplitView); + if (teamWindowSettings.FindMessage("consoleSplit", &archive) == B_OK) + GuiSettingsUtils::UnarchiveSplitView(archive, fConsoleSplitView); + if (teamWindowSettings.FindMessage("imageListView", &archive) == B_OK) fImageListView->LoadSettings(archive); @@ -491,6 +562,9 @@ TeamWindow::LoadSettings(const GuiTeamUiSettings* settings) if (teamWindowSettings.FindMessage("breakpointsView", &archive) == B_OK) fBreakpointsView->LoadSettings(archive); + if (teamWindowSettings.FindMessage("consoleOutputView", &archive) == B_OK) + fConsoleOutputView->LoadSettings(archive); + fUiSettings = *settings; return B_OK; @@ -535,6 +609,11 @@ TeamWindow::SaveSettings(GuiTeamUiSettings* settings) if (teamWindowSettings.AddMessage("threadSplit", &archive)) return B_NO_MEMORY; + if (GuiSettingsUtils::ArchiveSplitView(archive, fConsoleSplitView) != B_OK) + return B_NO_MEMORY; + if (teamWindowSettings.AddMessage("consoleSplit", &archive)) + return B_NO_MEMORY; + if (fImageListView->SaveSettings(archive) != B_OK) return B_NO_MEMORY; if (teamWindowSettings.AddMessage("imageListView", &archive)) @@ -570,6 +649,11 @@ TeamWindow::SaveSettings(GuiTeamUiSettings* settings) if (teamWindowSettings.AddMessage("breakpointsView", &archive)) return B_NO_MEMORY; + if (fConsoleOutputView->SaveSettings(archive) != B_OK) + return B_NO_MEMORY; + if (teamWindowSettings.AddMessage("consoleOutputView", &archive)) + return B_NO_MEMORY; + if (!settings->AddSettings("teamWindow", teamWindowSettings)) return B_NO_MEMORY; @@ -610,9 +694,17 @@ TeamWindow::FunctionSelectionChanged(FunctionInstance* function) void -TeamWindow::BreakpointSelectionChanged(UserBreakpoint* breakpoint) +TeamWindow::BreakpointSelectionChanged(BreakpointProxyList &proxies) { - _SetActiveBreakpoint(breakpoint); + if (proxies.CountItems() == 0 && fActiveBreakpoint != NULL) { + fActiveBreakpoint->ReleaseReference(); + fActiveBreakpoint = NULL; + } else if (proxies.CountItems() == 1) { + BreakpointProxy* proxy = proxies.ItemAt(0); + if (proxy->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) + _SetActiveBreakpoint(proxy->GetBreakpoint()); + } + // if more than one item is selected, do nothing. } @@ -646,9 +738,19 @@ TeamWindow::ClearBreakpointRequested(target_addr_t address) void -TeamWindow::WatchpointSelectionChanged(Watchpoint* watchpoint) +TeamWindow::ThreadActionRequested(::Thread* thread, uint32 action, + target_addr_t address) { - fBreakpointsView->SetBreakpoint(NULL, watchpoint); + if (fTraceUpdateRunner == NULL) + fListener->ThreadActionRequested(thread->ID(), action, address); +} + + +void +TeamWindow::FunctionSourceCodeRequested(FunctionInstance* function, + bool forceDisassembly) +{ + fListener->FunctionSourceCodeRequested(function, forceDisassembly); } @@ -711,6 +813,16 @@ TeamWindow::ImageDebugInfoChanged(const Team::ImageEvent& event) } +void +TeamWindow::ConsoleOutputReceived(const Team::ConsoleOutputEvent& event) +{ + BMessage message(MSG_CONSOLE_OUTPUT_RECEIVED); + message.AddInt32("fd", event.Descriptor()); + message.AddString("output", event.Output()); + PostMessage(&message); +} + + void TeamWindow::UserBreakpointChanged(const Team::UserBreakpointEvent& event) { @@ -773,9 +885,9 @@ TeamWindow::_Init() .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING) .AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING) .Add(fRunButton = new BButton("Run")) - .Add(fStepOverButton = new BButton("Step Over")) - .Add(fStepIntoButton = new BButton("Step Into")) - .Add(fStepOutButton = new BButton("Step Out")) + .Add(fStepOverButton = new BButton("Step over")) + .Add(fStepIntoButton = new BButton("Step into")) + .Add(fStepOutButton = new BButton("Step out")) .AddGlue() .End() .Add(fSourcePathView = new BStringView( @@ -786,6 +898,11 @@ TeamWindow::_Init() .End() .Add(fLocalsTabView = new BTabView("locals view")) .End() + .AddSplit(B_VERTICAL, splitSpacing) + .GetSplitView(&fConsoleSplitView) + .SetInsets(0.0) + .Add(fConsoleOutputView = ConsoleOutputView::Create()) + .End() .End(); // add source view @@ -845,7 +962,11 @@ TeamWindow::_Init() // add menus and menu items BMenu* menu = new BMenu("Team"); fMenuBar->AddItem(menu); - BMenuItem* item = new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED), + BMenuItem* item = new BMenuItem("Restart", new BMessage( + MSG_TEAM_RESTART_REQUESTED), 'R', B_SHIFT_KEY); + menu->AddItem(item); + item->SetTarget(this); + item = new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED), 'W'); menu->AddItem(item); item->SetTarget(this); @@ -854,16 +975,16 @@ TeamWindow::_Init() item = new BMenuItem("Copy", new BMessage(B_COPY), 'C'); menu->AddItem(item); item->SetTarget(this); - item = new BMenuItem("Select All", new BMessage(B_SELECT_ALL), 'A'); + item = new BMenuItem("Select all", new BMessage(B_SELECT_ALL), 'A'); menu->AddItem(item); item->SetTarget(this); menu = new BMenu("Tools"); fMenuBar->AddItem(menu); - item = new BMenuItem("Save Debug Report", + item = new BMenuItem("Save debug report", new BMessage(MSG_CHOOSE_DEBUG_REPORT_LOCATION)); menu->AddItem(item); item->SetTarget(this); - item = new BMenuItem("Inspect Memory", + item = new BMenuItem("Inspect memory", new BMessage(MSG_SHOW_INSPECTOR_WINDOW), 'I'); menu->AddItem(item); item->SetTarget(this); @@ -941,6 +1062,9 @@ TeamWindow::_SetActiveImage(Image* image) void TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace) { + delete fTraceUpdateRunner; + fTraceUpdateRunner = NULL; + if (stackTrace == fActiveStackTrace) return; @@ -953,10 +1077,12 @@ TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace) fActiveStackTrace->AcquireReference(); fStackTraceView->SetStackTrace(fActiveStackTrace); - fSourceView->SetStackTrace(fActiveStackTrace); + fSourceView->SetStackTrace(fActiveStackTrace, fActiveThread); if (fActiveStackTrace != NULL) _SetActiveStackFrame(fActiveStackTrace->FrameAt(0)); + else + _SetActiveStackFrame(NULL); } @@ -1033,8 +1159,6 @@ TeamWindow::_SetActiveBreakpoint(UserBreakpoint* breakpoint) // automatically, if the active function remains the same) _ScrollToActiveFunction(); } - - fBreakpointsView->SetBreakpoint(fActiveBreakpoint, NULL); } @@ -1172,12 +1296,14 @@ TeamWindow::_UpdateRunButtons() fStepOutButton->SetEnabled(false); break; case THREAD_STATE_RUNNING: - fRunButton->SetLabel("Debug"); - fRunButton->SetMessage(new BMessage(MSG_THREAD_STOP)); - fRunButton->SetEnabled(true); - fStepOverButton->SetEnabled(false); - fStepIntoButton->SetEnabled(false); - fStepOutButton->SetEnabled(false); + if (fTraceUpdateRunner == NULL) { + fRunButton->SetLabel("Debug"); + fRunButton->SetMessage(new BMessage(MSG_THREAD_STOP)); + fRunButton->SetEnabled(true); + fStepOverButton->SetEnabled(false); + fStepIntoButton->SetEnabled(false); + fStepOutButton->SetEnabled(false); + } break; case THREAD_STATE_STOPPED: fRunButton->SetLabel("Run"); @@ -1204,15 +1330,17 @@ TeamWindow::_UpdateSourcePathState() if (sourceFile != NULL && !sourceFile->GetLocatedPath(sourceText)) sourceFile->GetPath(sourceText); - if (fActiveSourceCode->GetSourceFile() == NULL && sourceFile != NULL) { + if (fActiveFunction->GetFunction()->SourceCodeState() + != FUNCTION_SOURCE_NOT_LOADED + && fActiveSourceCode->GetSourceFile() == NULL + && sourceFile != NULL) { sourceText.Prepend("Click to locate source file '"); sourceText += "'"; truncatedText = sourceText; fSourcePathView->TruncateString(&truncatedText, B_TRUNCATE_MIDDLE, fSourcePathView->Bounds().Width()); - } else if (sourceFile != NULL) { + } else if (sourceFile != NULL) sourceText.Prepend("File: "); - } } if (!truncatedText.IsEmpty() && truncatedText != sourceText) { @@ -1283,9 +1411,16 @@ TeamWindow::_HandleThreadStateChanged(thread_id threadID) } // Switch to the threads tab view when the thread has stopped. - if (thread->State() == THREAD_STATE_STOPPED) + if (thread->State() == THREAD_STATE_STOPPED) { fTabView->Select(MAIN_TAB_INDEX_THREADS); + // if we hit a breakpoint or exception, raise the window to the + // foreground, since if this occurs while e.g. debugging a GUI + // app, it might not be immediately obvious that such an event + // occurred as the app may simply appear to hang. + Activate(); + } + _UpdateRunButtons(); } @@ -1317,6 +1452,21 @@ TeamWindow::_HandleStackTraceChanged(thread_id threadID) locker.Unlock(); + if (stackTrace == NULL) { + if (fTraceUpdateRunner != NULL) + return; + + BMessage message(MSG_CLEAR_STACK_TRACE); + fTraceUpdateRunner = new(std::nothrow) BMessageRunner(this, + message, 250000, 1); + if (fTraceUpdateRunner != NULL + && fTraceUpdateRunner->InitCheck() == B_OK) { + fStackTraceView->SetStackTraceClearPending(); + fVariablesView->SetStackFrameClearPending(); + return; + } + } + _SetActiveStackTrace(stackTrace); } @@ -1357,8 +1507,11 @@ TeamWindow::_HandleSourceCodeChanged() // get a reference to the source code AutoLocker< ::Team> locker(fTeam); - SourceCode* sourceCode = fActiveFunction->GetFunction()->GetSourceCode(); - if (sourceCode == NULL) + SourceCode* sourceCode = NULL; + if (fActiveFunction->GetFunction()->SourceCodeState() + == FUNCTION_SOURCE_LOADED) { + sourceCode = fActiveFunction->GetFunction()->GetSourceCode(); + } else sourceCode = fActiveFunction->GetSourceCode(); BReference sourceCodeReference(sourceCode); @@ -1392,11 +1545,32 @@ TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath) ->SourceFile(); if (sourceFile != NULL) { BString sourcePath; - BString targetPath; sourceFile->GetPath(sourcePath); - BPath path(&locatedPath); - targetPath = path.Path(); - fListener->SourceEntryLocateRequested(sourcePath, targetPath); + BString sourceFileName(sourcePath); + int32 index = sourcePath.FindLast('/'); + if (index >= 0) + sourceFileName.Remove(0, index + 1); + + BPath targetFilePath(&locatedPath); + if (targetFilePath.InitCheck() != B_OK) + return; + + if (strcmp(sourceFileName.String(), targetFilePath.Leaf()) != 0) { + BString message; + message.SetToFormat("The names of source file '%s' and located" + " file '%s' differ. Use file anyway?", + sourceFileName.String(), targetFilePath.Leaf()); + BAlert* alert = new(std::nothrow) BAlert( + "Source path mismatch", message.String(), "Cancel", "Use"); + if (alert == NULL) + return; + + int32 choice = alert->Go(); + if (choice <= 0) + return; + } + fListener->SourceEntryLocateRequested(sourcePath, + targetFilePath.Path()); fListener->FunctionSourceCodeRequested(fActiveFunction); } } diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h index 2e8e8d487f..3ce67366fd 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010-2011, Rene Gollent, rene@gollent.com. + * Copyright 2010-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_WINDOW_H @@ -26,9 +26,12 @@ class BButton; class BFilePanel; class BMenuBar; +class BMessageRunner; class BSplitView; class BStringView; class BTabView; +class ConsoleOutputView; +class BreakConditionConfigWindow; class Image; class InspectorWindow; class RegistersView; @@ -88,15 +91,13 @@ private: // BreakpointsView::Listener virtual void BreakpointSelectionChanged( - UserBreakpoint* breakpoint); + BreakpointProxyList& proxies); virtual void SetBreakpointEnabledRequested( UserBreakpoint* breakpoint, bool enabled); virtual void ClearBreakpointRequested( UserBreakpoint* breakpoint); - virtual void WatchpointSelectionChanged( - Watchpoint* Watchpoint); virtual void SetWatchpointEnabledRequested( Watchpoint* breakpoint, bool enabled); @@ -107,7 +108,14 @@ private: // SourceView::Listener virtual void SetBreakpointRequested(target_addr_t address, bool enabled); - virtual void ClearBreakpointRequested(target_addr_t address); + virtual void ClearBreakpointRequested( + target_addr_t address); + virtual void ThreadActionRequested(::Thread* thread, + uint32 action, target_addr_t address); + virtual void FunctionSourceCodeRequested( + FunctionInstance* function, + bool forceDisassembly); + // VariablesView::Listener virtual void ValueNodeValueRequested(CpuState* cpuState, @@ -123,6 +131,8 @@ private: const Team::ThreadEvent& event); virtual void ImageDebugInfoChanged( const Team::ImageEvent& event); + virtual void ConsoleOutputReceived( + const Team::ConsoleOutputEvent& event); virtual void UserBreakpointChanged( const Team::UserBreakpointEvent& event); virtual void WatchpointChanged( @@ -173,6 +183,7 @@ private: SourceCode* fActiveSourceCode; ActiveSourceObject fActiveSourceObject; UserInterfaceListener* fListener; + BMessageRunner* fTraceUpdateRunner; BTabView* fTabView; BTabView* fLocalsTabView; ThreadListView* fThreadListView; @@ -189,10 +200,13 @@ private: BButton* fStepOutButton; BMenuBar* fMenuBar; BStringView* fSourcePathView; + ConsoleOutputView* fConsoleOutputView; BSplitView* fFunctionSplitView; BSplitView* fSourceSplitView; BSplitView* fImageSplitView; BSplitView* fThreadSplitView; + BSplitView* fConsoleSplitView; + BreakConditionConfigWindow* fBreakConditionConfigWindow; InspectorWindow* fInspectorWindow; GuiTeamUiSettings fUiSettings; BFilePanel* fFilePanel; diff --git a/src/apps/debugger/user_interface/gui/team_window/ThreadListView.cpp b/src/apps/debugger/user_interface/gui/team_window/ThreadListView.cpp index 6569fb9efe..f8c84dc043 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ThreadListView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/ThreadListView.cpp @@ -371,7 +371,7 @@ ThreadListView::_Init() B_TRUNCATE_END, B_ALIGN_LEFT)); fThreadsTable->AddColumn(new StringTableColumn(2, "Name", 200, 40, 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); - fThreadsTable->AddColumn(new StringTableColumn(3, "Stop Reason", + fThreadsTable->AddColumn(new StringTableColumn(3, "Stop reason", 200, 40, 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); fThreadsTable->SetSelectionMode(B_SINGLE_SELECTION_LIST); diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 1e1483d08a..113c6cb8f4 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -175,6 +175,9 @@ public: Type* GetType() const { + if (fCastedType != NULL) + return fCastedType; + return fNodeChild->GetType(); } @@ -928,16 +931,17 @@ VariablesView::VariableTableModel::SetStackFrame(Thread* thread, fNodeManager->SetStackFrame(thread, stackFrame); + int32 count = fNodes.CountItems(); fNodeTable.Clear(true); if (!fNodes.IsEmpty()) { - int32 count = fNodes.CountItems(); for (int32 i = 0; i < count; i++) fNodes.ItemAt(i)->ReleaseReference(); fNodes.MakeEmpty(); - NotifyNodesRemoved(TreeTablePath(), 0, count); } + NotifyNodesRemoved(TreeTablePath(), 0, count); + if (stackFrame == NULL) return; @@ -1107,7 +1111,7 @@ VariablesView::VariableTableModel::ValueNodeValueChanged(ValueNode* valueNode) int32 VariablesView::VariableTableModel::CountColumns() const { - return 2; + return 3; } @@ -1195,6 +1199,15 @@ VariablesView::VariableTableModel::GetValueAt(void* object, int32 columnIndex, _value.SetTo(node, VALUE_NODE_TYPE); return true; + case 2: + { + Type* type = node->GetType(); + if (type == NULL) + return false; + + _value.SetTo(type->Name(), B_VARIANT_DONT_COPY_DATA); + return true; + } default: return false; } @@ -1415,6 +1428,7 @@ VariablesView::VariablesView(Listener* listener) fPreviousViewState(NULL), fViewStateHistory(NULL), fTableCellContextMenuTracker(NULL), + fFrameClearPending(false), fListener(listener) { SetName("Variables"); @@ -1458,6 +1472,8 @@ VariablesView::Create(Listener* listener) void VariablesView::SetStackFrame(Thread* thread, StackFrame* stackFrame) { + fFrameClearPending = false; + if (thread == fThread && stackFrame == fStackFrame) return; @@ -1565,14 +1581,54 @@ VariablesView::MessageReceived(BMessage* message) break; } + BReference typeRef(type, true); ValueNode* valueNode = NULL; if (TypeHandlerRoster::Default()->CreateValueNode( - node->NodeChild(), type, valueNode) != B_OK) { + node->NodeChild(), type, valueNode) != B_OK) { break; } + typeRef.Detach(); node->NodeChild()->SetNode(valueNode); node->SetCastedType(type); + fVariableTableModel->NotifyNodeChanged(node); + break; + } + case MSG_TYPECAST_TO_ARRAY: + { + ModelNode* node = NULL; + if (message->FindPointer("node", reinterpret_cast(&node)) + != B_OK) { + break; + } + + Type* baseType = dynamic_cast(node->NodeChild() + ->Node()->GetType())->BaseType(); + ArrayType* arrayType = NULL; + if (baseType->CreateDerivedArrayType(0, kMaxArrayElementCount, + false, arrayType) != B_OK) { + break; + } + + AddressType* addressType = NULL; + BReference typeRef(arrayType, true); + if (arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER, + addressType) != B_OK) { + break; + } + + typeRef.Detach(); + typeRef.SetTo(addressType, true); + ValueNode* valueNode = NULL; + if (TypeHandlerRoster::Default()->CreateValueNode( + node->NodeChild(), addressType, valueNode) != B_OK) { + break; + } + + typeRef.Detach(); + node->NodeChild()->SetNode(valueNode); + node->SetCastedType(addressType); + fVariableTableModel->NotifyNodeChanged(node); break; } case MSG_SHOW_CONTAINER_RANGE_PROMPT: @@ -1581,8 +1637,17 @@ VariablesView::MessageReceived(BMessage* message) ->SelectionModel()->NodeAt(0); int32 lowerBound, upperBound; ValueNode* valueNode = node->NodeChild()->Node(); - if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK) + if (!valueNode->IsRangedContainer()) { + valueNode = node->ChildAt(0)->NodeChild()->Node(); + if (!valueNode->IsRangedContainer()) + break; + } + + bool fixedRange = valueNode->IsContainerRangeFixed(); + if (valueNode->SupportedChildRange(lowerBound, upperBound) + != B_OK) { break; + } BMessage* promptMessage = new(std::nothrow) BMessage( MSG_SET_CONTAINER_RANGE); @@ -1591,9 +1656,16 @@ VariablesView::MessageReceived(BMessage* message) ObjectDeleter messageDeleter(promptMessage); promptMessage->AddPointer("node", node); + promptMessage->AddBool("fixedRange", fixedRange); BString infoText; - infoText.SetToFormat("Allowed range: %" B_PRId32 - "-%" B_PRId32 ".", lowerBound, upperBound); + if (fixedRange) { + infoText.SetToFormat("Allowed range: %" B_PRId32 + "-%" B_PRId32 ".", lowerBound, upperBound); + } else { + infoText.SetToFormat("Current range: %" B_PRId32 + "-%" B_PRId32 ".", lowerBound, upperBound); + } + PromptWindow* promptWindow = new(std::nothrow) PromptWindow( "Set Range", "Range: ", infoText.String(), BMessenger(this), promptMessage); @@ -1611,16 +1683,20 @@ VariablesView::MessageReceived(BMessage* message) ->SelectionModel()->NodeAt(0); int32 lowerBound, upperBound; ValueNode* valueNode = node->NodeChild()->Node(); + if (!valueNode->IsRangedContainer()) + valueNode = node->ChildAt(0)->NodeChild()->Node(); if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK) break; + bool fixedRange = message->FindBool("fixedRange"); + BString rangeExpression = message->FindString("text"); if (rangeExpression.Length() == 0) break; RangeList ranges; status_t result = UiUtils::ParseRangeExpression( - rangeExpression, lowerBound, upperBound, ranges); + rangeExpression, lowerBound, upperBound, fixedRange, ranges); if (result != B_OK) break; @@ -1786,12 +1862,20 @@ VariablesView::SaveSettings(BMessage& settings) } +void +VariablesView::SetStackFrameClearPending() +{ + fFrameClearPending = true; +} void VariablesView::TreeTableNodeExpandedChanged(TreeTable* table, const TreeTablePath& path, bool expanded) { + if (fFrameClearPending) + return; + if (expanded) { ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path); if (node == NULL) @@ -1828,6 +1912,9 @@ VariablesView::TreeTableCellMouseDown(TreeTable* table, if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0) return; + if (fFrameClearPending) + return; + _FinishContextMenu(true); ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path); @@ -1886,6 +1973,8 @@ VariablesView::_Init() B_TRUNCATE_END, B_ALIGN_LEFT)); fVariableTable->AddColumn(new VariableValueColumn(1, "Value", 80, 40, 1000, B_TRUNCATE_END, B_ALIGN_RIGHT)); + fVariableTable->AddColumn(new StringTableColumn(2, "Type", 80, 40, 1000, + B_TRUNCATE_END, B_ALIGN_LEFT)); fVariableTableModel = new VariableTableModel; if (fVariableTableModel->Init() != B_OK) @@ -1966,6 +2055,18 @@ VariablesView::_GetContextActionsForNode(ModelNode* node, message->AddUInt64("address", location->PieceAt(0).address); } + ValueNode* valueNode = node->NodeChild()->Node(); + + if (valueNode != NULL) { + AddressType* type = dynamic_cast(valueNode->GetType()); + if (type != NULL && type->BaseType() != NULL) { + result = _AddContextAction("Cast to array", MSG_TYPECAST_TO_ARRAY, + actions, message); + if (result != B_OK) + return result; + message->AddPointer("node", node); + } + } result = _AddContextAction("Cast as" B_UTF8_ELLIPSIS, MSG_SHOW_TYPECAST_NODE_PROMPT, actions, message); @@ -1977,14 +2078,23 @@ VariablesView::_GetContextActionsForNode(ModelNode* node, if (result != B_OK) return result; - ValueNode* valueNode = node->NodeChild()->Node(); - if (valueNode != NULL && valueNode->IsRangedContainer()) { - result = _AddContextAction("Set visible range" B_UTF8_ELLIPSIS, - MSG_SHOW_CONTAINER_RANGE_PROMPT, actions, message); - if (result != B_OK) - return result; + if (valueNode == NULL) + return B_OK; + + if (!valueNode->IsRangedContainer()) { + if (node->CountChildren() == 1 && node->ChildAt(0)->IsHidden()) { + valueNode = node->ChildAt(0)->NodeChild()->Node(); + if (valueNode == NULL || !valueNode->IsRangedContainer()) + return B_OK; + } else + return B_OK; } + result = _AddContextAction("Set visible range" B_UTF8_ELLIPSIS, + MSG_SHOW_CONTAINER_RANGE_PROMPT, actions, message); + if (result != B_OK) + return result; + return B_OK; } diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h index 974190068d..9db6c3b53e 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -47,6 +47,8 @@ public: void LoadSettings(const BMessage& settings); status_t SaveSettings(BMessage& settings); + void SetStackFrameClearPending(); + private: // TreeTableListener virtual void TreeTableNodeExpandedChanged(TreeTable* table, @@ -94,6 +96,7 @@ private: VariablesViewState* fPreviousViewState; VariablesViewStateHistory* fViewStateHistory; TableCellContextMenuTracker* fTableCellContextMenuTracker; + bool fFrameClearPending; Listener* fListener; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp index 34ae3beb88..2363e28c6b 100644 --- a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp @@ -80,7 +80,7 @@ WatchPromptWindow::_Init() fArchitecture->GetWatchpointDebugCapabilities(maxDebugRegisters, maxBytesPerRegister, debugCapabilityFlags); - BMenu* typeMenu = new BMenu("Watch Type"); + BMenu* typeMenu = new BMenu("Watch type"); BMenuItem* watchTypeItem = new BMenuItem("Read", NULL); watchTypeItem->SetEnabled( diff --git a/src/apps/debugger/user_interface/util/UiUtils.cpp b/src/apps/debugger/user_interface/util/UiUtils.cpp index 6ed0c58e04..39eee3f784 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.cpp +++ b/src/apps/debugger/user_interface/util/UiUtils.cpp @@ -411,7 +411,7 @@ static status_t ParseRangeString(BString& rangeString, int32& lowerBound, /*static*/ status_t UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound, - int32 upperBound, RangeList& _output) + int32 upperBound, bool fixedRange, RangeList& _output) { if (rangeExpression.IsEmpty()) return B_BAD_DATA; @@ -440,7 +440,8 @@ UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound, if (result != B_OK) return result; - if (lowValue < lowerBound || highValue > upperBound) + + if (fixedRange && (lowValue < lowerBound || highValue > upperBound)) return B_BAD_VALUE; result = _output.AddRange(lowValue, highValue); diff --git a/src/apps/debugger/user_interface/util/UiUtils.h b/src/apps/debugger/user_interface/util/UiUtils.h index ccb67d51bc..7b11be9a18 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.h +++ b/src/apps/debugger/user_interface/util/UiUtils.h @@ -55,6 +55,7 @@ public: static status_t ParseRangeExpression( const BString& rangeString, int32 lowerBound, int32 upperBound, + bool fixedRange, RangeList& _output); }; diff --git a/src/apps/debugger/value/ValueNode.cpp b/src/apps/debugger/value/ValueNode.cpp index 1166f4cabd..33bde4f59c 100644 --- a/src/apps/debugger/value/ValueNode.cpp +++ b/src/apps/debugger/value/ValueNode.cpp @@ -70,6 +70,13 @@ ValueNode::IsRangedContainer() const } +bool +ValueNode::IsContainerRangeFixed() const +{ + return false; +} + + void ValueNode::ClearChildren() { diff --git a/src/apps/debugger/value/ValueNode.h b/src/apps/debugger/value/ValueNode.h index 9b88b77ebf..c61f252159 100644 --- a/src/apps/debugger/value/ValueNode.h +++ b/src/apps/debugger/value/ValueNode.h @@ -62,6 +62,10 @@ public: // node types to allow the upper layers to be aware of this, and to be // able to request that only a subset of children be created. virtual bool IsRangedContainer() const; + virtual bool IsContainerRangeFixed() const; + // indicates that the user can't + // arbitrarily go outside of the + // specified/supported range. virtual void ClearChildren(); virtual status_t CreateChildrenInRange(int32 lowIndex, int32 highIndex); diff --git a/src/apps/debugger/value/value_nodes/ArrayValueNode.cpp b/src/apps/debugger/value/value_nodes/ArrayValueNode.cpp index 6752c9b156..bc05323c02 100644 --- a/src/apps/debugger/value/value_nodes/ArrayValueNode.cpp +++ b/src/apps/debugger/value/value_nodes/ArrayValueNode.cpp @@ -31,7 +31,10 @@ AbstractArrayValueNode::AbstractArrayValueNode(ValueNodeChild* nodeChild, : ValueNode(nodeChild), fType(type), - fDimension(dimension) + fDimension(dimension), + fLowerBound(0), + fUpperBound(0), + fBoundsInitialized(false) { fType->AcquireReference(); } @@ -106,6 +109,8 @@ void AbstractArrayValueNode::ClearChildren() { fChildren.MakeEmpty(); + fLowerBound = 0; + fUpperBound = 0; if (fContainer != NULL) fContainer->NotifyValueNodeChildrenDeleted(this); } @@ -121,14 +126,22 @@ AbstractArrayValueNode::CreateChildrenInRange(int32 lowIndex, int32 dimensionCount = fType->CountDimensions(); bool isFinalDimension = fDimension + 1 == dimensionCount; + status_t error = B_OK; - int32 lowerBound, upperBound; - if (SupportedChildRange(lowerBound, upperBound) == B_OK) { - // clamp inputs to supported range. - if (lowIndex < lowerBound) - lowIndex = lowerBound; - if (highIndex > upperBound) - highIndex = upperBound; + if (!fBoundsInitialized) { + int32 lowerBound, upperBound; + error = SupportedChildRange(lowerBound, upperBound); + if (error != B_OK) + return error; + + fLowerBound = lowerBound; + fUpperBound = upperBound; + fBoundsInitialized = true; + } else { + if (lowIndex < fLowerBound) + fLowerBound = lowIndex; + if (highIndex > fUpperBound) + fUpperBound = highIndex; } // create children for the array elements @@ -166,19 +179,23 @@ status_t AbstractArrayValueNode::SupportedChildRange(int32& lowIndex, int32& highIndex) const { - ArrayDimension* dimension = fType->DimensionAt(fDimension); + if (!fBoundsInitialized) { + ArrayDimension* dimension = fType->DimensionAt(fDimension); - SubrangeType* dimensionType = dynamic_cast( - dimension->GetType()); + SubrangeType* dimensionType = dynamic_cast( + dimension->GetType()); - if (dimensionType != NULL) { - lowIndex = dimensionType->LowerBound().ToInt32(); - highIndex = dimensionType->UpperBound().ToInt32(); - - return B_OK; + if (dimensionType != NULL) { + lowIndex = dimensionType->LowerBound().ToInt32(); + highIndex = dimensionType->UpperBound().ToInt32(); + } else + return B_UNSUPPORTED; + } else { + lowIndex = fLowerBound; + highIndex = fUpperBound; } - return B_UNSUPPORTED; + return B_OK; } diff --git a/src/apps/debugger/value/value_nodes/ArrayValueNode.h b/src/apps/debugger/value/value_nodes/ArrayValueNode.h index cc305e7528..242954dfcf 100644 --- a/src/apps/debugger/value/value_nodes/ArrayValueNode.h +++ b/src/apps/debugger/value/value_nodes/ArrayValueNode.h @@ -54,6 +54,9 @@ protected: ArrayType* fType; ChildList fChildren; int32 fDimension; + int32 fLowerBound; + int32 fUpperBound; + bool fBoundsInitialized; }; diff --git a/src/apps/debugger/value/value_nodes/BListValueNode.cpp b/src/apps/debugger/value/value_nodes/BListValueNode.cpp index 1e949b21cb..147dccde2f 100644 --- a/src/apps/debugger/value/value_nodes/BListValueNode.cpp +++ b/src/apps/debugger/value/value_nodes/BListValueNode.cpp @@ -330,6 +330,13 @@ BListValueNode::IsRangedContainer() const } +bool +BListValueNode::IsContainerRangeFixed() const +{ + return true; +} + + void BListValueNode::ClearChildren() { diff --git a/src/apps/debugger/value/value_nodes/BListValueNode.h b/src/apps/debugger/value/value_nodes/BListValueNode.h index e4347b68f3..ce34e013e0 100644 --- a/src/apps/debugger/value/value_nodes/BListValueNode.h +++ b/src/apps/debugger/value/value_nodes/BListValueNode.h @@ -37,6 +37,7 @@ public: virtual ValueNodeChild* ChildAt(int32 index) const; virtual bool IsRangedContainer() const; + virtual bool IsContainerRangeFixed() const; virtual void ClearChildren(); virtual status_t CreateChildrenInRange(int32 lowIndex, int32 highIndex); diff --git a/src/apps/deskbar/ExpandoMenuBar.cpp b/src/apps/deskbar/ExpandoMenuBar.cpp index 84615b073a..5f56fc4bf3 100644 --- a/src/apps/deskbar/ExpandoMenuBar.cpp +++ b/src/apps/deskbar/ExpandoMenuBar.cpp @@ -90,6 +90,7 @@ TExpandoMenuBar::TExpandoMenuBar(BRect frame, const char* name, fExpandNewTeams(static_cast(be_app)->Settings()->expandNewTeams), fDeskbarMenuWidth(kMinMenuItemWidth), fPreviousDragTargetItem(NULL), + fLastMousedOverItem(NULL), fLastClickedItem(NULL), fClickedExpander(false) { @@ -370,7 +371,7 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) case B_INSIDE_VIEW: { - BMenuItem* menuItem = NULL; + BMenuItem* menuItem; TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); TWindowMenuItem* windowMenuItem = dynamic_cast(menuItem); @@ -397,6 +398,7 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) SetToolTip(windowMenuItem->FullTitle()); } else SetToolTip((const char*)NULL); + break; } @@ -407,12 +409,10 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) break; } - // new item, set the tooltip to the item name SetToolTip(item->Name()); - - // save the current menuitem for the next MouseMoved() call + // new item, set the tooltip to the item name fLastMousedOverItem = menuItem; - + // save the current menuitem for the next MouseMoved() call break; } @@ -423,8 +423,8 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) { TTeamMenuItem* lastItem = dynamic_cast(fLastClickedItem); - if (fVertical && fShowTeamExpander && fClickedExpander - && lastItem != NULL) { + if (lastItem != NULL && fVertical && fShowTeamExpander + && fClickedExpander) { // Started expander animation, then exited view, // since we can't track outside mouse movements // redraw the original expander arrow @@ -715,15 +715,9 @@ TExpandoMenuBar::RemoveTeam(team_id team, bool partial) if (TTeamMenuItem* item = dynamic_cast(ItemAt(i))) { if (item->Teams()->HasItem((void*)(addr_t)team)) { item->Teams()->RemoveItem(team); - if (partial) return; -#ifdef DOUBLECLICKBRINGSTOFRONT - if (fLastClickedItem == i) - fLastClickedItem = -1; -#endif - BAutolock locker(sMonLocker); // make the update thread wait RemoveItem(i); diff --git a/src/apps/deskbar/ExpandoMenuBar.h b/src/apps/deskbar/ExpandoMenuBar.h index 663f8ea9d9..6cb2b7d066 100644 --- a/src/apps/deskbar/ExpandoMenuBar.h +++ b/src/apps/deskbar/ExpandoMenuBar.h @@ -45,13 +45,6 @@ All rights reserved. #include -class BBitmap; -class TBarView; -class TBarMenuTitle; -class TTeamMenuItem; - -//#define DOUBLECLICKBRINGSTOFRONT - enum drag_and_drop_selection { kNoSelection, kDeskbarMenuSelection, @@ -59,6 +52,13 @@ enum drag_and_drop_selection { kAnyMenuSelection }; + +class BBitmap; +class TBarView; +class TBarMenuTitle; +class TTeamMenuItem; + + class TExpandoMenuBar : public BMenuBar { public: TExpandoMenuBar(BRect frame, const char* name, diff --git a/src/apps/deskbar/PreferencesWindow.cpp b/src/apps/deskbar/PreferencesWindow.cpp index 06d76491c8..480d7e2196 100644 --- a/src/apps/deskbar/PreferencesWindow.cpp +++ b/src/apps/deskbar/PreferencesWindow.cpp @@ -224,6 +224,7 @@ PreferencesWindow::PreferencesWindow(BRect frame) BBox* windowSettingsBox = new BBox("window"); windowSettingsBox->SetLabel(B_TRANSLATE("Window")); windowSettingsBox->AddChild(BLayoutBuilder::Group<>() + .SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)) .AddGroup(B_VERTICAL, 0) .Add(fWindowAlwaysOnTop) .Add(fWindowAutoRaise) diff --git a/src/apps/deskcalc/CalcView.cpp b/src/apps/deskcalc/CalcView.cpp index c9a0f9c400..0f20cffc9a 100644 --- a/src/apps/deskcalc/CalcView.cpp +++ b/src/apps/deskcalc/CalcView.cpp @@ -602,7 +602,7 @@ CalcView::MouseUp(BPoint point) void CalcView::KeyDown(const char* bytes, int32 numBytes) { - // if single byte character... + // if single byte character... if (numBytes == 1) { //printf("Key pressed: %c\n", bytes[0]); @@ -674,7 +674,6 @@ void CalcView::ResizeTo(float width, float height) { BView::ResizeTo(width, height); - FrameResized(width, height); } diff --git a/src/apps/deskcalc/ExpressionTextView.cpp b/src/apps/deskcalc/ExpressionTextView.cpp index ae27e55553..4f8d3d3665 100644 --- a/src/apps/deskcalc/ExpressionTextView.cpp +++ b/src/apps/deskcalc/ExpressionTextView.cpp @@ -244,10 +244,15 @@ ExpressionTextView::SetValue(BString value) } } - // add the exponent - offset = value.CountChars() - 1; - if (exponent != 0) + if (exponent != 0) { + value.Truncate(40); + // truncate to a reasonable precision + // while ensuring result will be rounded + offset = value.CountChars() - 1; value << "E" << exponent; + // add the exponent + } else + offset = value.CountChars() - 1; // reduce the number of digits until the string fits or can not be // made any shorter @@ -281,8 +286,8 @@ ExpressionTextView::SetValue(BString value) } if (digit == 10) { // carry over, shift the result - if (value[firstDigit+1] == '.') { - value[firstDigit+1] = '0'; + if (value[firstDigit + 1] == '.') { + value[firstDigit + 1] = '0'; value[firstDigit] = '.'; } value.Insert('1', 1, firstDigit); diff --git a/src/apps/expander/ExpanderWindow.cpp b/src/apps/expander/ExpanderWindow.cpp index 5d642717e8..aa2ed3ad6c 100644 --- a/src/apps/expander/ExpanderWindow.cpp +++ b/src/apps/expander/ExpanderWindow.cpp @@ -1,6 +1,7 @@ /* * Copyright 2004-2006, Jérôme DUVAL. All rights reserved. * Copyright 2010, Karsten Heimrich. All rights reserved. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -15,8 +16,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -64,10 +64,7 @@ ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref, fSettings(*settings), fPreferences(NULL) { - BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 0); - SetLayout(layout); - - _AddMenuBar(layout); + _CreateMenuBar(); fDestButton = new BButton(B_TRANSLATE("Destination"), new BMessage(MSG_DEST)); @@ -100,34 +97,40 @@ ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref, BString statusPlaceholderString; statusPlaceholderString.SetTo(' ', MAX_STATUS_LENGTH * 2); - BView* topView = layout->View(); const float spacing = be_control_look->DefaultItemSpacing(); - topView->AddChild(BGroupLayoutBuilder(B_VERTICAL, spacing) - .AddGroup(B_HORIZONTAL, spacing) - .AddGroup(B_VERTICAL, 5.0) - .Add(fSourceButton) - .Add(fDestButton) - .Add(fExpandButton) - .End() - .AddGroup(B_VERTICAL, spacing) - .Add(fSourceText = new BTextControl(NULL, NULL, - new BMessage(MSG_SOURCETEXT))) - .Add(fDestText = new BTextControl(NULL, NULL, - new BMessage(MSG_DESTTEXT))) - .AddGroup(B_HORIZONTAL, spacing) - .Add(fShowContents = new BCheckBox( - B_TRANSLATE("Show contents"), - new BMessage(MSG_SHOWCONTENTS))) - .Add(fStatusView = new BStringView(NULL, - statusPlaceholderString)) + BGroupLayout* pathLayout; + BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0) + .SetInsets(0.0) + .Add(fBar) + .AddGroup(B_VERTICAL, spacing) + .AddGroup(B_HORIZONTAL, spacing) + .AddGroup(B_VERTICAL, 5.0) + .Add(fSourceButton) + .Add(fDestButton) + .Add(fExpandButton) + .End() + .AddGroup(B_VERTICAL, spacing) + .Add(fSourceText = new BTextControl(NULL, NULL, + new BMessage(MSG_SOURCETEXT))) + .Add(fDestText = new BTextControl(NULL, NULL, + new BMessage(MSG_DESTTEXT))) + .AddGroup(B_HORIZONTAL, spacing) + .GetLayout(&pathLayout) + .Add(fShowContents = new BCheckBox( + B_TRANSLATE("Show contents"), + new BMessage(MSG_SHOWCONTENTS))) + .Add(fStatusView = new BStringView(NULL, + statusPlaceholderString)) + .End() .End() .End() + .Add(scrollView) + .SetInsets(spacing, spacing, spacing, spacing) .End() - .Add(scrollView) - .SetInsets(spacing, spacing, spacing, spacing) - ); + .End(); - size = topView->PreferredSize(); + pathLayout->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); + size = GetLayout()->View()->PreferredSize(); fSizeLimit = size.Height() - scrollView->PreferredSize().height - spacing; ResizeTo(Bounds().Width(), fSizeLimit); @@ -380,7 +383,7 @@ ExpanderWindow::MessageReceived(BMessage* msg) if (strstr(string.String(), "Enter password") != NULL) { fExpandingThread->SuspendExternalExpander(); BString password; - PasswordAlert* alert = + PasswordAlert* alert = new PasswordAlert("passwordAlert", string); alert->Go(password); fExpandingThread->ResumeExternalExpander(); @@ -389,8 +392,8 @@ ExpanderWindow::MessageReceived(BMessage* msg) } } break; - - case 'errp': + + case 'errp': { BString string; if (msg->FindString("error", &string) == B_OK @@ -550,7 +553,7 @@ ExpanderWindow::RefsReceived(BMessage* msg) #define B_TRANSLATION_CONTEXT "ExpanderMenu" void -ExpanderWindow::_AddMenuBar(BLayout* layout) +ExpanderWindow::_CreateMenuBar() { fBar = new BMenuBar("menu_bar", B_ITEMS_IN_ROW, B_INVALIDATE_AFTER_LAYOUT); BMenu* menu = new BMenu(B_TRANSLATE("File")); @@ -578,7 +581,6 @@ ExpanderWindow::_AddMenuBar(BLayout* layout) menu->AddItem(fPreferencesItem = new BMenuItem(B_TRANSLATE("Settings…"), new BMessage(MSG_PREFERENCES), 'S')); fBar->AddItem(menu); - layout->AddView(fBar); } diff --git a/src/apps/expander/ExpanderWindow.h b/src/apps/expander/ExpanderWindow.h index dcc56d0bb2..53f72f411b 100644 --- a/src/apps/expander/ExpanderWindow.h +++ b/src/apps/expander/ExpanderWindow.h @@ -41,7 +41,7 @@ public: void RefsReceived(BMessage* msg); private: - void _AddMenuBar(BLayout* layout); + void _CreateMenuBar(); bool CanQuit(); // returns true if the window can be closed safely, false if not void CloseWindowOrKeepOpen(); diff --git a/src/apps/fontdemo/ControlView.cpp b/src/apps/fontdemo/ControlView.cpp index 80e069a49a..66d8c104c3 100644 --- a/src/apps/fontdemo/ControlView.cpp +++ b/src/apps/fontdemo/ControlView.cpp @@ -71,14 +71,14 @@ ControlView::AttachedToWindow() fTextControl = new BTextControl(rect, "TextInput", B_TRANSLATE("Text:"), B_TRANSLATE("Haiku, Inc."), NULL); - fTextControl->SetDivider(29.0); + fTextControl->SetDivider(36.0); fTextControl->SetModificationMessage(new BMessage(TEXT_CHANGED_MSG)); AddChild(fTextControl); rect.OffsetBy(0.0, 27.0); _AddFontMenu(rect); - rect.OffsetBy(0.0, 29.0); + rect.OffsetBy(0.0, 36.0); fFontsizeSlider = new BSlider(rect, "Fontsize", B_TRANSLATE("Size: 50"), NULL, 4, 360); fFontsizeSlider->SetModificationMessage(new BMessage(FONTSIZE_MSG)); @@ -122,59 +122,15 @@ ControlView::AttachedToWindow() fAliasingCheckBox->SetValue(B_CONTROL_ON); AddChild(fAliasingCheckBox); - rect.OffsetBy(0.0, offsetX); - fDrawingModeMenu = new BMenu("drawingmodemenu"); + rect.OffsetBy(0.0, 30.0f); + _AddDrawingModeMenu(rect); - BMessage* drawingMsg = NULL; - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_COPY); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_COPY", drawingMsg)); - fDrawingModeMenu->ItemAt(0)->SetMarked(true); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_OVER); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_OVER", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_ERASE); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_ERASE", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_INVERT); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_INVERT", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_ADD); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_ADD", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_SUBTRACT); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_SUBTRACT", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_BLEND); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_BLEND", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_MIN); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_MIN", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_MAX); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_MAX", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_SELECT); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_SELECT", drawingMsg)); - drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); - drawingMsg->AddInt32("_mode", B_OP_ALPHA); - fDrawingModeMenu->AddItem(new BMenuItem("B_OP_ALPHA", drawingMsg)); - - fDrawingModeMenu->SetLabelFromMarked(true); - - BMenuField *drawingModeMenuField = new BMenuField(rect, "FontMenuField", - B_TRANSLATE("Drawing mode:"), fDrawingModeMenu, true); - drawingModeMenuField->SetDivider(5+StringWidth( - B_TRANSLATE("Drawing mode:"))); - AddChild(drawingModeMenuField); - - rect.OffsetBy(0.0, 22); + rect.OffsetBy(0.0, 30.0f); fBoundingboxesCheckBox = new BCheckBox(rect, "BoundingBoxes", B_TRANSLATE("Bounding boxes"), new BMessage(BOUNDING_BOX_MSG)); AddChild(fBoundingboxesCheckBox); - rect.OffsetBy(0.0, 22.0); + rect.OffsetBy(0.0, 30.0f); fCyclingFontButton = new BButton(rect, "Cyclefonts", B_TRANSLATE("Cycle fonts"), new BMessage(CYCLING_FONTS_MSG)); AddChild(fCyclingFontButton); @@ -472,13 +428,67 @@ ControlView::_AddFontMenu(BRect rect) _UpdateFontmenus(true); + rect.bottom += 4; fFontMenuField = new BMenuField(rect, "FontMenuField", B_TRANSLATE("Font:"), fFontFamilyMenu, true); - fFontMenuField->SetDivider(30.0); + fFontMenuField->SetDivider( + fFontMenuField->StringWidth(B_TRANSLATE("Font:")) + 5); AddChild(fFontMenuField); } +void +ControlView::_AddDrawingModeMenu(BRect rect) +{ + fDrawingModeMenu = new BMenu("drawingmodemenu"); + + BMessage* drawingMsg = NULL; + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_COPY); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_COPY", drawingMsg)); + fDrawingModeMenu->ItemAt(0)->SetMarked(true); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_OVER); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_OVER", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_ERASE); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_ERASE", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_INVERT); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_INVERT", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_ADD); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_ADD", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_SUBTRACT); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_SUBTRACT", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_BLEND); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_BLEND", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_MIN); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_MIN", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_MAX); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_MAX", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_SELECT); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_SELECT", drawingMsg)); + drawingMsg = new BMessage(DRAWINGMODE_CHANGED_MSG); + drawingMsg->AddInt32("_mode", B_OP_ALPHA); + fDrawingModeMenu->AddItem(new BMenuItem("B_OP_ALPHA", drawingMsg)); + + fDrawingModeMenu->SetLabelFromMarked(true); + + rect.bottom += 4; + BMenuField* drawingModeMenuField = new BMenuField(rect, "FontMenuField", + B_TRANSLATE("Drawing mode:"), fDrawingModeMenu, true); + drawingModeMenuField->SetDivider( + fDrawingModeMenu->StringWidth(B_TRANSLATE("Drawing mode:") + 5)); + AddChild(drawingModeMenuField); +} + + void ControlView::_UpdateAndSendFamily(const BMessage* message) { diff --git a/src/apps/fontdemo/ControlView.h b/src/apps/fontdemo/ControlView.h index ff1c0c958a..0e347ed493 100644 --- a/src/apps/fontdemo/ControlView.h +++ b/src/apps/fontdemo/ControlView.h @@ -36,6 +36,7 @@ class ControlView : public BView { private: void _AddFontMenu(BRect rect); + void _AddDrawingModeMenu(BRect rect); void _UpdateFontmenus(bool setInitialfont = false); void _DeselectOldItems(); diff --git a/src/apps/fontdemo/FontDemo.cpp b/src/apps/fontdemo/FontDemo.cpp index b8092329ce..94206c499a 100644 --- a/src/apps/fontdemo/FontDemo.cpp +++ b/src/apps/fontdemo/FontDemo.cpp @@ -29,7 +29,7 @@ FontDemo::FontDemo() FontDemoView* demoView = new FontDemoView(demoWindow->Bounds()); demoWindow->AddChild(demoView); - BWindow* controlWindow = new BWindow(BRect(500, 30, 700, 402), B_TRANSLATE("Controls"), + BWindow* controlWindow = new BWindow(BRect(500, 30, 700, 420), B_TRANSLATE("Controls"), B_FLOATING_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL, B_NOT_CLOSABLE | B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS); diff --git a/src/apps/mail/Header.cpp b/src/apps/mail/Header.cpp index 2fc6165461..485c7e6c16 100644 --- a/src/apps/mail/Header.cpp +++ b/src/apps/mail/Header.cpp @@ -170,7 +170,7 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, dummy->RemoveSelf(); delete dummy; - float menuFieldHeight = menuBarHeight + 6; + float menuFieldHeight = menuBarHeight + 2; float controlHeight = menuBarHeight + floorf(be_plain_font->Size() / 1.15); if (!fIncoming) { diff --git a/src/apps/mediaplayer/settings/SettingsWindow.cpp b/src/apps/mediaplayer/settings/SettingsWindow.cpp index 989acc6c1d..ea1cc176c4 100644 --- a/src/apps/mediaplayer/settings/SettingsWindow.cpp +++ b/src/apps/mediaplayer/settings/SettingsWindow.cpp @@ -48,7 +48,7 @@ SettingsWindow::SettingsWindow(BRect frame) | B_AUTO_UPDATE_SIZE_LIMITS) { const float kSpacing = be_control_look->DefaultItemSpacing(); - + BBox* settingsBox = new BBox(B_PLAIN_BORDER, NULL); BGroupLayout* settingsLayout = new BGroupLayout(B_VERTICAL, kSpacing / 2); settingsBox->SetLayout(settingsLayout); @@ -135,13 +135,18 @@ SettingsWindow::SettingsWindow(BRect frame) okButton->MakeDefault(true); // Build the layout + BGroupLayout* volumeGroup; + BGroupLayout* startGroup; + BGroupLayout* playGroup; BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .AddGroup(settingsLayout) .SetInsets(kSpacing, kSpacing, kSpacing * 2, 0) .Add(playModeLabel) .AddGroup(B_HORIZONTAL, 0) - .AddStrut(kSpacing) + .GetLayout(&playGroup) + .AddStrut(10) .AddGroup(B_VERTICAL, 0) + .GetLayout(&startGroup) .Add(fAutostartCB) .AddGrid(kSpacing, 0) .Add(BSpaceLayoutItem::CreateHorizontalStrut(kSpacing), 0, 0) @@ -172,6 +177,7 @@ SettingsWindow::SettingsWindow(BRect frame) .AddGroup(B_HORIZONTAL, 0) .AddStrut(10) .AddGroup(B_VERTICAL, 0) + .GetLayout(&volumeGroup) .Add(fFullVolumeBGMoviesRB) .Add(fHalfVolumeBGMoviesRB) .Add(fMutedVolumeBGMoviesRB) @@ -185,6 +191,10 @@ SettingsWindow::SettingsWindow(BRect frame) .AddGlue() .Add(cancelButton) .Add(okButton); + + startGroup->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); + playGroup->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); + volumeGroup->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); } diff --git a/src/apps/people/PersonView.cpp b/src/apps/people/PersonView.cpp index 656bef1021..9d25a22ed3 100644 --- a/src/apps/people/PersonView.cpp +++ b/src/apps/people/PersonView.cpp @@ -55,10 +55,10 @@ PersonView::PersonView(const char* name, const char* categoryAttribute, SetName(name); SetFlags(Flags() | B_WILL_DRAW); - if (ref) - fFile = new BFile(ref, O_RDWR); - else - fFile = NULL; + fRef = ref; + BFile* file = NULL; + if (fRef != NULL) + file = new BFile(fRef, B_READ_ONLY); float spacing = be_control_look->DefaultItemSpacing(); BGridLayout* layout = GridLayout(); @@ -71,14 +71,14 @@ PersonView::PersonView(const char* name, const char* categoryAttribute, layout->ItemAt(0, 0)->SetExplicitAlignment( BAlignment(B_ALIGN_CENTER, B_ALIGN_TOP)); - if (fFile) - fFile->GetModificationTime(&fLastModificationTime); + if (file != NULL) + file->GetModificationTime(&fLastModificationTime); + delete file; } PersonView::~PersonView() { - delete fFile; } @@ -269,8 +269,7 @@ PersonView::BuildGroupMenu() void PersonView::CreateFile(const entry_ref* ref) { - delete fFile; - fFile = new BFile(ref, B_READ_WRITE); + fRef = ref; Save(); } @@ -293,13 +292,17 @@ PersonView::IsSaved() const void PersonView::Save() { + BFile file(fRef, B_READ_WRITE); + if (file.InitCheck() != B_NO_ERROR) + return; + fSaving = true; int32 count = fControls.CountItems(); for (int32 i = 0; i < count; i++) { AttributeTextControl* control = fControls.ItemAt(i); const char* value = control->Text(); - fFile->WriteAttr(control->Attribute().String(), B_STRING_TYPE, 0, + file.WriteAttr(control->Attribute().String(), B_STRING_TYPE, 0, value, strlen(value) + 1); control->Update(); } @@ -307,8 +310,8 @@ PersonView::Save() // Write the picture, if any, in the person file content if (fPictureView) { // Trim any previous content - fFile->Seek(0, SEEK_SET); - fFile->SetSize(0); + file.Seek(0, SEEK_SET); + file.SetSize(0); BBitmap* picture = fPictureView->Bitmap(); if (picture) { @@ -318,7 +321,7 @@ PersonView::Save() stream.DetachBitmap(&picture); BTranslatorRoster* roster = BTranslatorRoster::Default(); - roster->Translate(&stream, NULL, NULL, fFile, + roster->Translate(&stream, NULL, NULL, &file, fPictureView->SuggestedType(), B_TRANSLATOR_BITMAP, fPictureView->SuggestedMIMEType()); @@ -327,7 +330,7 @@ PersonView::Save() fPictureView->Update(); } - fFile->GetModificationTime(&fLastModificationTime); + file.GetModificationTime(&fLastModificationTime); fSaving = false; } @@ -350,14 +353,20 @@ PersonView::SetAttribute(const char* attribute, bool update) { char* value = NULL; attr_info info; - if (fFile != NULL && fFile->GetAttrInfo(attribute, &info) == B_OK) { + BFile* file = NULL; + + if (fRef != NULL) + file = new(std::nothrow) BFile(fRef, B_READ_ONLY); + + if (file != NULL && file->GetAttrInfo(attribute, &info) == B_OK) { value = (char*)calloc(info.size, 1); - fFile->ReadAttr(attribute, B_STRING_TYPE, 0, value, info.size); + file->ReadAttr(attribute, B_STRING_TYPE, 0, value, info.size); } SetAttribute(attribute, value, update); free(value); + delete file; } diff --git a/src/apps/people/PersonView.h b/src/apps/people/PersonView.h index 3695b22e50..f6ecc27941 100644 --- a/src/apps/people/PersonView.h +++ b/src/apps/people/PersonView.h @@ -62,7 +62,7 @@ public: bool IsTextSelected() const; private: - BFile* fFile; + const entry_ref* fRef; time_t fLastModificationTime; BPopUpMenu* fGroups; typedef BObjectList AttributeList; diff --git a/src/apps/processcontroller/ProcessController.cpp b/src/apps/processcontroller/ProcessController.cpp index 17aae5c4b6..eadb0c0edb 100644 --- a/src/apps/processcontroller/ProcessController.cpp +++ b/src/apps/processcontroller/ProcessController.cpp @@ -1,7 +1,7 @@ /* ProcessController © 2000, Georges-Edouard Berenger, All Rights Reserved. Copyright (C) 2004 beunited.org - Copyright (c) 2006-2012, Haiku, Inc. All rights reserved. + Copyright (c) 2006-2013, Haiku, Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -69,6 +69,9 @@ const char* kFrameColorPref = "deskbar_frame_color"; const char* kIdleColorPref = "deskbar_idle_color"; const char* kActiveColorPref = "deskbar_active_color"; +static const char* const kDebuggerSignature + = "application/x-vnd.Haiku-Debugger"; + const rgb_color kKernelBlue = {20, 20, 231, 255}; const rgb_color kIdleGreen = {110, 190,110, 255}; @@ -220,6 +223,23 @@ ProcessController::Init() } +void +ProcessController::_HandleDebugRequest(team_id team, thread_id thread) +{ + char *argv[2]; + char paramString[16]; + char idString[16]; + strlcpy(paramString, thread > 0 ? "--thread" : "--team", sizeof(paramString)); + snprintf(idString, sizeof(idString), "%" B_PRId32, thread > 0 ? thread : team); + argv[0] = paramString; + argv[1] = idString; + status_t error = be_roster->Launch(kDebuggerSignature, 2, argv); + if (error != B_OK) { + // TODO: notify user + } +} + + ProcessController* ProcessController::Instantiate(BMessage *data) { @@ -267,14 +287,24 @@ ProcessController::MessageReceived(BMessage *message) if (get_team_info(team, &infos.team_info) == B_OK) { get_team_name_and_icon(infos); snprintf(question, sizeof(question), - B_TRANSLATE("Do you really want to kill the team \"%s\"?"), + B_TRANSLATE("What do you want to do with the team \"%s\"?"), infos.team_name); alert = new BAlert(B_TRANSLATE("Please confirm"), question, - B_TRANSLATE("Cancel"), B_TRANSLATE("Yes, kill this team!"), - NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT); + B_TRANSLATE("Cancel"), B_TRANSLATE("Debug this team!"), + B_TRANSLATE("Kill this team!"), B_WIDTH_AS_USUAL, + B_STOP_ALERT); alert->SetShortcut(0, B_ESCAPE); - if (alert->Go()) - kill_team(team); + int result = alert->Go(); + switch (result) { + case 1: + _HandleDebugRequest(team, -1); + break; + case 2: + kill_team(team); + break; + default: + break; + } } else { alert = new BAlert(B_TRANSLATE("Info"), B_TRANSLATE("This team is already gone"B_UTF8_ELLIPSIS), @@ -317,17 +347,8 @@ ProcessController::MessageReceived(BMessage *message) if (r == KILL) kill_thread(thread); #if DEBUG_THREADS - else if (r == 1) { - Tdebug_thead_param* param = new Tdebug_thead_param; - param->thread = thread; - if (thinfo.state == B_THREAD_WAITING) - param->sem = thinfo.sem; - else - param->sem = -1; - param->totalTime = thinfo.user_time+thinfo.kernel_time; - resume_thread(spawn_thread(thread_debug_thread, - B_TRANSLATE("Debug thread"), B_NORMAL_PRIORITY, param)); - } + else if (r == 1) + _HandleDebugRequest(thinfo.team, thinfo.thread); #endif } else { alert = new BAlert(B_TRANSLATE("Info"), diff --git a/src/apps/processcontroller/ProcessController.h b/src/apps/processcontroller/ProcessController.h index f51142784d..02cd76f067 100644 --- a/src/apps/processcontroller/ProcessController.h +++ b/src/apps/processcontroller/ProcessController.h @@ -1,21 +1,21 @@ /* ProcessController © 2000, Georges-Edouard Berenger, All Rights Reserved. Copyright (C) 2004 beunited.org - Copyright (c) 2006-2012, Haiku, Inc. All rights reserved. + Copyright (c) 2006-2013, Haiku, Inc. All rights reserved. - This library 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. + This library 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. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PCVIEW_H_ #define _PCVIEW_H_ @@ -58,6 +58,7 @@ class ProcessController : public BView { private: void Init(); + void _HandleDebugRequest(team_id team, thread_id thread); bool fTemp; float fMemoryUsage; diff --git a/src/apps/stylededit/StyledEditWindow.cpp b/src/apps/stylededit/StyledEditWindow.cpp index 4469d1d2f8..4eee321e08 100644 --- a/src/apps/stylededit/StyledEditWindow.cpp +++ b/src/apps/stylededit/StyledEditWindow.cpp @@ -1825,7 +1825,7 @@ StyledEditWindow::_ShowStatistics() size_t length = fTextView->TextLength(); for (size_t i = 0; i < length; i++) { - if (BUnicodeChar::IsSpace(fTextView->Text()[i])) { + if (BUnicodeChar::IsWhitespace(fTextView->Text()[i])) { inWord = false; } else if (!inWord) { words++; diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index c2b1edacd9..b86fbe52f3 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -1048,8 +1048,19 @@ TermParse::EscParse() uchar params[512]; // fill the buffer until BEL, ST or something else. bool isParsed = false; + int32 skipCount = 0; // take care about UTF-8 characters for (uint i = 0; !isParsed && i < sizeof(params); i++) { params[i] = _NextParseChar(); + + if (skipCount > 0) { + skipCount--; + continue; + } + + skipCount = UTF8Char::ByteCount(params[i]) - 1; + if (skipCount > 0) + continue; + switch (params[i]) { // BEL case 0x07: @@ -1074,6 +1085,9 @@ TermParse::EscParse() params[i] = '\0'; } + // watchdog for the 'end of buffer' case + params[sizeof(params) - 1] = '\0'; + if (isParsed) _ProcessOperatingSystemControls(params); diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 073a697279..9b57d18dd6 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -735,27 +735,8 @@ TermWindow::MessageReceived(BMessage *message) fFindPanel = new FindWindow(this, fFindString, fFindSelection, fMatchWord, fMatchCase, fForwardSearch); - // position the window under the mouse pointer - BPoint where; - uint32 buttons; - ChildAt(0)->GetMouse(&where, &buttons); - fFindPanel->MoveTo(ConvertToScreen(where)); - - // move window if outside of screen frame - BRect screenFrame = (BScreen(this)).Frame(); - BRect frame = fFindPanel->Frame(); - float extra = 30.0f; - if (frame.bottom + extra * 2 > screenFrame.bottom) { - fFindPanel->MoveBy(0, - screenFrame.bottom - frame.bottom - extra * 2); - } else if (frame.top - extra < screenFrame.top) - fFindPanel->MoveBy(0, screenFrame.top - frame.top + extra); - - if (frame.right + extra > screenFrame.right) { - fFindPanel->MoveBy(screenFrame.right - frame.right - - extra, 0); - } - + fFindPanel->CenterIn(Frame()); + _MoveWindowInScreen(fFindPanel); fFindPanel->Show(); } else fFindPanel->Activate(); @@ -910,7 +891,7 @@ TermWindow::MessageReceived(BMessage *message) // done before ResizeTo to work around a Dano bug // (not erasing the decor) SetLook(B_NO_BORDER_WINDOW_LOOK); - ResizeTo(screen.Frame().Width()+1, screen.Frame().Height()+1); + ResizeTo(screen.Frame().Width() + 1, screen.Frame().Height() + 1); MoveTo(screen.Frame().left, screen.Frame().top); SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_MOVABLE)); fFullScreen = true; @@ -1869,10 +1850,8 @@ TermWindow::_OpenSetTabTitleDialog(int32 index) // place the dialog window directly under the tab, but keep it on screen BPoint location = fTabView->ConvertToScreen( fTabView->TabFrame(index).LeftBottom() + BPoint(0, 1)); - BRect frame(fSetTabTitleDialog->Frame().OffsetToCopy(location)); - BSize screenSize(BScreen(fSetTabTitleDialog).Frame().Size()); - fSetTabTitleDialog->MoveTo( - BLayoutUtils::MoveIntoFrame(frame, screenSize).LeftTop()); + fSetTabTitleDialog->MoveTo(location); + _MoveWindowInScreen(fSetTabTitleDialog); fSetTabTitleDialog->Go(title, userDefined, this); } @@ -1892,10 +1871,7 @@ TermWindow::_OpenSetWindowTitleDialog() // center the dialog in the window frame, but keep it on screen fSetWindowTitleDialog->CenterIn(Frame()); - BRect frame(fSetWindowTitleDialog->Frame()); - BSize screenSize(BScreen(fSetWindowTitleDialog).Frame().Size()); - fSetWindowTitleDialog->MoveTo( - BLayoutUtils::MoveIntoFrame(frame, screenSize).LeftTop()); + _MoveWindowInScreen(fSetWindowTitleDialog); fSetWindowTitleDialog->Go(fTitle.pattern, fTitle.patternUserDefined, this); } @@ -2007,3 +1983,12 @@ TermWindow::_NewSessionIndex() return id; } } + + +void +TermWindow::_MoveWindowInScreen(BWindow* window) +{ + BRect frame = window->Frame(); + BSize screenSize(BScreen(window).Frame().Size()); + window->MoveTo(BLayoutUtils::MoveIntoFrame(frame, screenSize).LeftTop()); +} diff --git a/src/apps/terminal/TermWindow.h b/src/apps/terminal/TermWindow.h index 542603a6ef..5740595445 100644 --- a/src/apps/terminal/TermWindow.h +++ b/src/apps/terminal/TermWindow.h @@ -185,6 +185,8 @@ private: SessionID _NewSessionID(); int32 _NewSessionIndex(); + void _MoveWindowInScreen(BWindow* window); + private: TerminalRoster fTerminalRoster; diff --git a/src/apps/webpositive/AuthenticationPanel.cpp b/src/apps/webpositive/AuthenticationPanel.cpp index 79112712c0..bfcde2da89 100644 --- a/src/apps/webpositive/AuthenticationPanel.cpp +++ b/src/apps/webpositive/AuthenticationPanel.cpp @@ -1,30 +1,8 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ - #include "AuthenticationPanel.h" #include diff --git a/src/apps/webpositive/AuthenticationPanel.h b/src/apps/webpositive/AuthenticationPanel.h index 5af9496aad..cb8b91410b 100644 --- a/src/apps/webpositive/AuthenticationPanel.h +++ b/src/apps/webpositive/AuthenticationPanel.h @@ -1,30 +1,8 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ - #ifndef AuthenticationPanel_h #define AuthenticationPanel_h diff --git a/src/apps/webpositive/BrowserApp.cpp b/src/apps/webpositive/BrowserApp.cpp index 131952d1fb..5b17b6cde9 100644 --- a/src/apps/webpositive/BrowserApp.cpp +++ b/src/apps/webpositive/BrowserApp.cpp @@ -47,7 +47,6 @@ #include "DownloadWindow.h" #include "SettingsMessage.h" #include "SettingsWindow.h" -#include "svn_revision.h" #include "NetworkCookieJar.h" #include "WebKitInfo.h" #include "WebPage.h" diff --git a/src/apps/webpositive/BrowserWindow.cpp b/src/apps/webpositive/BrowserWindow.cpp index 7785796913..b833da0c50 100644 --- a/src/apps/webpositive/BrowserWindow.cpp +++ b/src/apps/webpositive/BrowserWindow.cpp @@ -462,19 +462,19 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings, } // Back, Forward, Stop & Home buttons - fBackButton = new IconButton("Back", 0, NULL, new BMessage(GO_BACK)); + fBackButton = new BIconButton("Back", NULL, new BMessage(GO_BACK)); fBackButton->SetIcon(201); fBackButton->TrimIcon(); - fForwardButton = new IconButton("Forward", 0, NULL, new BMessage(GO_FORWARD)); + fForwardButton = new BIconButton("Forward", NULL, new BMessage(GO_FORWARD)); fForwardButton->SetIcon(202); fForwardButton->TrimIcon(); - fStopButton = new IconButton("Stop", 0, NULL, new BMessage(STOP)); + fStopButton = new BIconButton("Stop", NULL, new BMessage(STOP)); fStopButton->SetIcon(204); fStopButton->TrimIcon(); - fHomeButton = new IconButton("Home", 0, NULL, new BMessage(HOME)); + fHomeButton = new BIconButton("Home", NULL, new BMessage(HOME)); fHomeButton->SetIcon(206); fHomeButton->TrimIcon(); if (!fAppSettings->GetValue(kSettingsKeyShowHomeButton, true)) diff --git a/src/apps/webpositive/BrowserWindow.h b/src/apps/webpositive/BrowserWindow.h index bf80d75396..5b87aa3a4c 100644 --- a/src/apps/webpositive/BrowserWindow.h +++ b/src/apps/webpositive/BrowserWindow.h @@ -47,11 +47,16 @@ class BStatusBar; class BStringView; class BTextControl; class BWebView; -class IconButton; class SettingsMessage; class TabManager; class URLInputGroup; +namespace BPrivate { + class BIconButton; +} + +using BPrivate::BIconButton; + enum { INTERFACE_ELEMENT_MENU = 1 << 0, INTERFACE_ELEMENT_TABS = 1 << 1, @@ -214,10 +219,10 @@ private: BMenuItem* fBackMenuItem; BMenuItem* fForwardMenuItem; - IconButton* fBackButton; - IconButton* fForwardButton; - IconButton* fStopButton; - IconButton* fHomeButton; + BIconButton* fBackButton; + BIconButton* fForwardButton; + BIconButton* fStopButton; + BIconButton* fHomeButton; URLInputGroup* fURLInputGroup; BStringView* fStatusText; BStatusBar* fLoadingProgressBar; diff --git a/src/apps/webpositive/BrowsingHistory.cpp b/src/apps/webpositive/BrowsingHistory.cpp index 42a0442d0f..665656407e 100644 --- a/src/apps/webpositive/BrowsingHistory.cpp +++ b/src/apps/webpositive/BrowsingHistory.cpp @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "BrowsingHistory.h" diff --git a/src/apps/webpositive/BrowsingHistory.h b/src/apps/webpositive/BrowsingHistory.h index bf8f7f15b8..18b7ff1836 100644 --- a/src/apps/webpositive/BrowsingHistory.h +++ b/src/apps/webpositive/BrowsingHistory.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef BROWSING_HISTORY_H #define BROWSING_HISTORY_H diff --git a/src/apps/webpositive/CredentialsStorage.cpp b/src/apps/webpositive/CredentialsStorage.cpp index ab5f8eae8d..bd5498b5a7 100644 --- a/src/apps/webpositive/CredentialsStorage.cpp +++ b/src/apps/webpositive/CredentialsStorage.cpp @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "CredentialsStorage.h" diff --git a/src/apps/webpositive/CredentialsStorage.h b/src/apps/webpositive/CredentialsStorage.h index 214c36b371..26767ae62d 100644 --- a/src/apps/webpositive/CredentialsStorage.h +++ b/src/apps/webpositive/CredentialsStorage.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef CREDENTIAL_STORAGE_H #define CREDENTIAL_STORAGE_H diff --git a/src/apps/webpositive/DownloadProgressView.cpp b/src/apps/webpositive/DownloadProgressView.cpp index aef948b467..b192e2067b 100644 --- a/src/apps/webpositive/DownloadProgressView.cpp +++ b/src/apps/webpositive/DownloadProgressView.cpp @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "DownloadProgressView.h" diff --git a/src/apps/webpositive/DownloadProgressView.h b/src/apps/webpositive/DownloadProgressView.h index 32a021b169..cfe9e52ec9 100644 --- a/src/apps/webpositive/DownloadProgressView.h +++ b/src/apps/webpositive/DownloadProgressView.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef DOWNLOAD_PROGRESS_VIEW_H #define DOWNLOAD_PROGRESS_VIEW_H diff --git a/src/apps/webpositive/DownloadWindow.cpp b/src/apps/webpositive/DownloadWindow.cpp index dee9867602..503e64511e 100644 --- a/src/apps/webpositive/DownloadWindow.cpp +++ b/src/apps/webpositive/DownloadWindow.cpp @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "DownloadWindow.h" diff --git a/src/apps/webpositive/DownloadWindow.h b/src/apps/webpositive/DownloadWindow.h index d76661ba4e..3b6dec5a86 100644 --- a/src/apps/webpositive/DownloadWindow.h +++ b/src/apps/webpositive/DownloadWindow.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef DOWNLOAD_WINDOW_H #define DOWNLOAD_WINDOW_H diff --git a/src/apps/webpositive/Jamfile b/src/apps/webpositive/Jamfile index a287626480..584d37794d 100644 --- a/src/apps/webpositive/Jamfile +++ b/src/apps/webpositive/Jamfile @@ -26,11 +26,8 @@ local sources = # support BaseURL.cpp BitmapButton.cpp - DateTime.cpp FontSelectionView.cpp - IconButton.cpp SettingsMessage.cpp - StringForSize.cpp # tabview TabContainerView.cpp @@ -46,7 +43,6 @@ local sources = DownloadWindow.cpp SettingsKeys.cpp SettingsWindow.cpp - svn_revision.cpp URLInputGroup.cpp ; @@ -54,12 +50,11 @@ Includes [ FGristFiles $(sources) ] : $(HAIKU_WEBKIT_HEADERS_DEPENDENCY) ; # Dependency needed to trigger downloading/unzipping the package before # compiling the files. -# SVN revision -#local svnRevisionFile = [ FGristFiles svn_revision ] ; -#MakeLocate $(svnRevisionFile) : $(LOCATE_TARGET) ; -#CreateSVNRevisionFile $(svnRevisionFile) ; +# private OS headers +UseLibraryHeaders icon ; +UsePrivateHeaders shared tracker ; +SubDirHdrs $(HAIKU_TOP) src kits tracker ; -UsePrivateHeaders shared ; Application WebPositive : $(sources) diff --git a/src/apps/webpositive/SettingsKeys.cpp b/src/apps/webpositive/SettingsKeys.cpp index 448fd33902..7d106d1be5 100644 --- a/src/apps/webpositive/SettingsKeys.cpp +++ b/src/apps/webpositive/SettingsKeys.cpp @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "SettingsKeys.h" diff --git a/src/apps/webpositive/SettingsKeys.h b/src/apps/webpositive/SettingsKeys.h index ebc38f2165..71a0999504 100644 --- a/src/apps/webpositive/SettingsKeys.h +++ b/src/apps/webpositive/SettingsKeys.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef SETTINGS_KEYS_H #define SETTINGS_KEYS_H diff --git a/src/apps/webpositive/SettingsWindow.cpp b/src/apps/webpositive/SettingsWindow.cpp index 1803542065..93473dd51d 100644 --- a/src/apps/webpositive/SettingsWindow.cpp +++ b/src/apps/webpositive/SettingsWindow.cpp @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "SettingsWindow.h" diff --git a/src/apps/webpositive/SettingsWindow.h b/src/apps/webpositive/SettingsWindow.h index 66b2289191..eabfc5a460 100644 --- a/src/apps/webpositive/SettingsWindow.h +++ b/src/apps/webpositive/SettingsWindow.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef SETTINGS_WINDOW_H #define SETTINGS_WINDOW_H diff --git a/src/apps/webpositive/support/AutoLocker.h b/src/apps/webpositive/support/AutoLocker.h deleted file mode 100644 index 9baa7aa7a5..0000000000 --- a/src/apps/webpositive/support/AutoLocker.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2005-2007, Ingo Weinhold, bonefish@users.sf.net. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _AUTO_LOCKER_H -#define _AUTO_LOCKER_H - - -#include - - -namespace BPrivate { - -// AutoLockerStandardLocking -template -class AutoLockerStandardLocking { -public: - inline bool Lock(Lockable* lockable) - { - return lockable->Lock(); - } - - inline void Unlock(Lockable* lockable) - { - lockable->Unlock(); - } -}; - -// AutoLockerReadLocking -template -class AutoLockerReadLocking { -public: - inline bool Lock(Lockable* lockable) - { - return lockable->ReadLock(); - } - - inline void Unlock(Lockable* lockable) - { - lockable->ReadUnlock(); - } -}; - -// AutoLockerWriteLocking -template -class AutoLockerWriteLocking { -public: - inline bool Lock(Lockable* lockable) - { - return lockable->WriteLock(); - } - - inline void Unlock(Lockable* lockable) - { - lockable->WriteUnlock(); - } -}; - -// AutoLocker -template > -class AutoLocker { -private: - typedef AutoLocker ThisClass; -public: - inline AutoLocker() - : - fLockable(NULL), - fLocked(false) - { - } - - inline AutoLocker(const Locking& locking) - : - fLockable(NULL), - fLocking(locking), - fLocked(false) - { - } - - inline AutoLocker(Lockable* lockable, bool alreadyLocked = false, - bool lockIfNotLocked = true) - : - fLockable(lockable), - fLocked(fLockable && alreadyLocked) - { - if (!alreadyLocked && lockIfNotLocked) - Lock(); - } - - inline AutoLocker(Lockable& lockable, bool alreadyLocked = false, - bool lockIfNotLocked = true) - : - fLockable(&lockable), - fLocked(fLockable && alreadyLocked) - { - if (!alreadyLocked && lockIfNotLocked) - Lock(); - } - - inline ~AutoLocker() - { - Unlock(); - } - - inline void SetTo(Lockable* lockable, bool alreadyLocked, - bool lockIfNotLocked = true) - { - Unlock(); - fLockable = lockable; - fLocked = (lockable && alreadyLocked); - if (!alreadyLocked && lockIfNotLocked) - Lock(); - } - - inline void SetTo(Lockable& lockable, bool alreadyLocked, - bool lockIfNotLocked = true) - { - SetTo(&lockable, alreadyLocked, lockIfNotLocked); - } - - inline void Unset() - { - Unlock(); - Detach(); - } - - inline bool Lock() - { - if (fLockable && !fLocked) - fLocked = fLocking.Lock(fLockable); - return fLocked; - } - - inline void Unlock() - { - if (fLockable && fLocked) { - fLocking.Unlock(fLockable); - fLocked = false; - } - } - - inline void Detach() - { - fLockable = NULL; - fLocked = false; - } - - inline AutoLocker& operator=(Lockable* lockable) - { - SetTo(lockable); - return *this; - } - - inline AutoLocker& operator=(Lockable& lockable) - { - SetTo(&lockable); - return *this; - } - - inline bool IsLocked() const { return fLocked; } - - inline operator bool() const { return fLocked; } - -protected: - Lockable* fLockable; - Locking fLocking; - bool fLocked; -}; - - -} // namespace BPrivate - -using BPrivate::AutoLocker; -using BPrivate::AutoLockerReadLocking; -using BPrivate::AutoLockerWriteLocking; - -#endif // _AUTO_LOCKER_H diff --git a/src/apps/webpositive/support/DateTime.cpp b/src/apps/webpositive/support/DateTime.cpp deleted file mode 100644 index 19030db00a..0000000000 --- a/src/apps/webpositive/support/DateTime.cpp +++ /dev/null @@ -1,1473 +0,0 @@ -/* - * Copyright 2007-2010, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Julun - * Stephan Aßmus - */ - -#include "DateTime.h" - - -#include -#include - -#include - - -namespace BPrivate { - - -const int32 kSecondsPerMinute = 60; - -const int32 kHoursPerDay = 24; -const int32 kMinutesPerDay = 1440; -const int32 kSecondsPerDay = 86400; -const int32 kMillisecondsPerDay = 86400000; - -const bigtime_t kMicrosecondsPerSecond = 1000000LL; -const bigtime_t kMicrosecondsPerMinute = 60000000LL; -const bigtime_t kMicrosecondsPerHour = 3600000000LL; -const bigtime_t kMicrosecondsPerDay = 86400000000LL; - - -/*! - Constructs a new BTime object. Asked for its time representation, it will - return 0 for Hour(), Minute(), Second() etc. This can represent midnight, - but be aware IsValid() will return false. -*/ -BTime::BTime() - : - fMicroseconds(-1) -{ -} - - -/*! - Constructs a new BTime object as a copy of \c other. -*/ -BTime::BTime(const BTime& other) - : - fMicroseconds(other.fMicroseconds) -{ -} - - -/*! - Constructs a BTime object with \c hour \c minute, \c second, \c microsecond. - - \c hour must be between 0 and 23, \c minute and \c second must be between - 0 and 59 and \c microsecond should be in the range of 0 and 999999. If the - specified time is invalid, the time is not set and IsValid() returns false. -*/ -BTime::BTime(int32 hour, int32 minute, int32 second, int32 microsecond) - : - fMicroseconds(-1) -{ - _SetTime(hour, minute, second, microsecond); -} - - -/*! - Constructs a new BTime object from the provided BMessage archive. -*/ -BTime::BTime(const BMessage* archive) - : - fMicroseconds(-1) -{ - if (archive == NULL) - return; - archive->FindInt64("mircoseconds", &fMicroseconds); -} - - -/*! - Empty destructor. -*/ -BTime::~BTime() -{ -} - - -/*! - Archives the BTime object into the provided BMessage object. - @returns \c B_OK if all went well. - \c B_BAD_VALUE, if the message is \c NULL. - \c other error codes, depending on failure to append - fields to the message. -*/ -status_t -BTime::Archive(BMessage* into) const -{ - if (into == NULL) - return B_BAD_VALUE; - return into->AddInt64("mircoseconds", fMicroseconds); -} - - -/*! - Returns true if the time is valid, otherwise false. A valid time can be - BTime(23, 59, 59, 999999) while BTime(24, 00, 01) would be invalid. -*/ -bool -BTime::IsValid() const -{ - return fMicroseconds > -1 && fMicroseconds < kMicrosecondsPerDay; -} - - -/*! - This is an overloaded member function, provided for convenience. -*/ -bool -BTime::IsValid(const BTime& time) const -{ - return time.fMicroseconds > -1 && time.fMicroseconds < kMicrosecondsPerDay; -} - - -/*! - This is an overloaded member function, provided for convenience. -*/ -bool -BTime::IsValid(int32 hour, int32 minute, int32 second, int32 microsecond) const -{ - return BTime(hour, minute, second, microsecond).IsValid(); -} - - -/*! - Returns the current time as reported by the system depending on the given - time_type \c type. -*/ -BTime -BTime::CurrentTime(time_type type) -{ - struct timeval tv; - if (gettimeofday(&tv, NULL) != 0) { - // gettimeofday failed? - time(&tv.tv_sec); - } - - struct tm result; - struct tm* timeinfo; - if (type == B_GMT_TIME) - timeinfo = gmtime_r(&tv.tv_sec, &result); - else - timeinfo = localtime_r(&tv.tv_sec, &result); - - int32 sec = timeinfo->tm_sec; - return BTime(timeinfo->tm_hour, timeinfo->tm_min, (sec > 59) ? 59 : sec, - tv.tv_usec); -} - - -/*! - Returns a copy of the current BTime object. -*/ -BTime -BTime::Time() const -{ - return *this; -} - - -/*! - This is an overloaded member function, provided for convenience. Set the - current BTime object to the passed BTime \c time object. -*/ -bool -BTime::SetTime(const BTime& time) -{ - fMicroseconds = time.fMicroseconds; - return IsValid(); -} - - -/*! - Set the time to \c hour \c minute, \c second and \c microsecond. - - \c hour must be between 0 and 23, \c minute and \c second must be between - 0 and 59 and \c microsecond should be in the range of 0 and 999999. Returns - true if the time is valid; otherwise false. If the specified time is - invalid, the time is not set and the function returns false. -*/ -bool -BTime::SetTime(int32 hour, int32 minute, int32 second, int32 microsecond) -{ - return _SetTime(hour, minute, second, microsecond); -} - - - -/*! - Adds \c hours to the current time. If the passed value is negativ it will - become earlier. Note: The time will wrap if it passes midnight. -*/ -BTime& -BTime::AddHours(int32 hours) -{ - return _AddMicroseconds(bigtime_t(hours % kHoursPerDay) - * kMicrosecondsPerHour); -} - - -/*! - Adds \c minutes to the current time. If the passed value is negativ it will - become earlier. Note: The time will wrap if it passes midnight. -*/ -BTime& -BTime::AddMinutes(int32 minutes) -{ - return _AddMicroseconds(bigtime_t(minutes % kMinutesPerDay) - * kMicrosecondsPerMinute); -} - - -/*! - Adds \c seconds to the current time. If the passed value is negativ it will - become earlier. Note: The time will wrap if it passes midnight. -*/ -BTime& -BTime::AddSeconds(int32 seconds) -{ - return _AddMicroseconds(bigtime_t(seconds % kSecondsPerDay) - * kMicrosecondsPerSecond); -} - - -/*! - Adds \c milliseconds to the current time. If the passed value is negativ it - will become earlier. Note: The time will wrap if it passes midnight. -*/ -BTime& -BTime::AddMilliseconds(int32 milliseconds) -{ - return _AddMicroseconds(bigtime_t(milliseconds % kMillisecondsPerDay) - * 1000); -} - - -/*! - Adds \c microseconds to the current time. If the passed value is negativ it - will become earlier. Note: The time will wrap if it passes midnight. -*/ -BTime& -BTime::AddMicroseconds(int32 microseconds) -{ - return _AddMicroseconds(microseconds); -} - - -/*! - Returns the hour fragment of the time. -*/ -int32 -BTime::Hour() const -{ - return int32(_Microseconds() / kMicrosecondsPerHour); -} - - -/*! - Returns the minute fragment of the time. -*/ -int32 -BTime::Minute() const -{ - return int32(((_Microseconds() % kMicrosecondsPerHour)) / kMicrosecondsPerMinute); -} - - -/*! - Returns the second fragment of the time. -*/ -int32 -BTime::Second() const -{ - return int32(_Microseconds() / kMicrosecondsPerSecond) % kSecondsPerMinute; -} - - -/*! - Returns the millisecond fragment of the time. -*/ -int32 -BTime::Millisecond() const -{ - - return Microsecond() / 1000; -} - - -/*! - Returns the microsecond fragment of the time. -*/ -int32 -BTime::Microsecond() const -{ - return int32(_Microseconds() % 1000000); -} - - -bigtime_t -BTime::_Microseconds() const -{ - return fMicroseconds == -1 ? 0 : fMicroseconds; -} - - -/*! - Returns the difference between this time and the given BTime \c time based - on the passed diff_type \c type. If \c time is earlier the return value will - be negativ. - - The return value then can be hours, minutes, seconds, milliseconds or - microseconds while its range will always be between -86400000000 and - 86400000000 depending on diff_type \c type. -*/ -bigtime_t -BTime::Difference(const BTime& time, diff_type type) const -{ - bigtime_t diff = time._Microseconds() - _Microseconds(); - switch (type) { - case B_HOURS_DIFF: { - diff /= kMicrosecondsPerHour; - } break; - case B_MINUTES_DIFF: { - diff /= kMicrosecondsPerMinute; - } break; - case B_SECONDS_DIFF: { - diff /= kMicrosecondsPerSecond; - } break; - case B_MILLISECONDS_DIFF: { - diff /= 1000; - } break; - case B_MICROSECONDS_DIFF: - default: break; - } - return diff; -} - - -/*! - Returns true if this time is different from \c time, otherwise false. -*/ -bool -BTime::operator!=(const BTime& time) const -{ - return fMicroseconds != time.fMicroseconds; -} - - -/*! - Returns true if this time is equal to \c time, otherwise false. -*/ -bool -BTime::operator==(const BTime& time) const -{ - return fMicroseconds == time.fMicroseconds; -} - - -/*! - Returns true if this time is earlier than \c time, otherwise false. -*/ -bool -BTime::operator<(const BTime& time) const -{ - return fMicroseconds < time.fMicroseconds; -} - - -/*! - Returns true if this time is earlier than or equal to \c time, otherwise false. -*/ -bool -BTime::operator<=(const BTime& time) const -{ - return fMicroseconds <= time.fMicroseconds; -} - - -/*! - Returns true if this time is later than \c time, otherwise false. -*/ -bool -BTime::operator>(const BTime& time) const -{ - return fMicroseconds > time.fMicroseconds; -} - - -/*! - Returns true if this time is later than or equal to \c time, otherwise false. -*/ -bool -BTime::operator>=(const BTime& time) const -{ - return fMicroseconds >= time.fMicroseconds; -} - - -BTime& -BTime::_AddMicroseconds(bigtime_t microseconds) -{ - bigtime_t count = 0; - if (microseconds < 0) { - count = ((kMicrosecondsPerDay - microseconds) / kMicrosecondsPerDay) * - kMicrosecondsPerDay; - } - fMicroseconds = (_Microseconds() + microseconds + count) % kMicrosecondsPerDay; - return *this; -} - - -bool -BTime::_SetTime(bigtime_t hour, bigtime_t minute, bigtime_t second, - bigtime_t microsecond) -{ - fMicroseconds = hour * kMicrosecondsPerHour + - minute * kMicrosecondsPerMinute + - second * kMicrosecondsPerSecond + - microsecond; - - bool isValid = IsValid(); - if (!isValid) - fMicroseconds = -1; - - return isValid; -} - - -// #pragma mark - BDate - - -/*! - Constructs a new BDate object. IsValid() will return false. -*/ -BDate::BDate() - : - fDay(-1), - fYear(0), - fMonth(-1) -{ -} - - -/*! - Constructs a new BDate object as a copy of \c other. -*/ -BDate::BDate(const BDate& other) - : - fDay(other.fDay), - fYear(other.fYear), - fMonth(other.fMonth) -{ -} - - -/*! - Constructs a BDate object with \c year \c month and \c day. - - Please note that a date before 1.1.4713 BC, a date with year 0 and a date - between 4.10.1582 and 15.10.1582 are considered invalid. If the specified - date is invalid, the date is not set and IsValid() returns false. Also note - that every passed year will be interpreted as is. - -*/ -BDate::BDate(int32 year, int32 month, int32 day) -{ - _SetDate(year, month, day); -} - - -/*! - Constructs a new BDate object from the provided archive. -*/ -BDate::BDate(const BMessage* archive) - : - fDay(-1), - fYear(0), - fMonth(-1) -{ - if (archive == NULL) - return; - archive->FindInt32("day", &fDay); - archive->FindInt32("year", &fYear); - archive->FindInt32("month", &fMonth); -} - - -/*! - Empty destructor. -*/ -BDate::~BDate() -{ -} - - -/*! - Archives the BDate object into the provided BMessage object. - @returns \c B_OK if all went well. - \c B_BAD_VALUE, if the message is \c NULL. - \c other error codes, depending on failure to append - fields to the message. -*/ -status_t -BDate::Archive(BMessage* into) const -{ - if (into == NULL) - return B_BAD_VALUE; - status_t ret = into->AddInt32("day", fDay); - if (ret == B_OK) - ret = into->AddInt32("year", fYear); - if (ret == B_OK) - ret = into->AddInt32("month", fMonth); - return ret; -} - - -/*! - Returns true if the date is valid, otherwise false. - - Please note that a date before 1.1.4713 BC, a date with year 0 and a date - between 4.10.1582 and 15.10.1582 are considered invalid. -*/ -bool -BDate::IsValid() const -{ - return IsValid(fYear, fMonth, fDay); -} - - -/*! - This is an overloaded member function, provided for convenience. -*/ -bool -BDate::IsValid(const BDate& date) const -{ - return IsValid(date.fYear, date.fMonth, date.fDay); -} - - -/*! - This is an overloaded member function, provided for convenience. -*/ -bool -BDate::IsValid(int32 year, int32 month, int32 day) const -{ - // no year 0 in Julian and nothing before 1.1.4713 BC - if (year == 0 || year < -4713) - return false; - - if (month < 1 || month > 12) - return false; - - if (day < 1 || day > _DaysInMonth(year, month)) - return false; - - // 'missing' days between switch julian - gregorian - if (year == 1582 && month == 10 && day > 4 && day < 15) - return false; - - return true; -} - - -/*! - Returns the current date as reported by the system depending on the given - time_type \c type. -*/ -BDate -BDate::CurrentDate(time_type type) -{ - time_t timer; - struct tm result; - struct tm* timeinfo; - - time(&timer); - - if (type == B_GMT_TIME) - timeinfo = gmtime_r(&timer, &result); - else - timeinfo = localtime_r(&timer, &result); - - return BDate(timeinfo->tm_year + 1900, timeinfo->tm_mon +1, timeinfo->tm_mday); -} - - -/*! - Returns a copy of the current BTime object. -*/ -BDate -BDate::Date() const -{ - return *this; -} - - -/*! - This is an overloaded member function, provided for convenience. -*/ -bool -BDate::SetDate(const BDate& date) -{ - return _SetDate(date.fYear, date.fMonth, date.fDay); -} - - -/*! - Set the date to \c year \c month and \c day. - - Returns true if the date is valid; otherwise false. If the specified date is - invalid, the date is not set and the function returns false. -*/ -bool -BDate::SetDate(int32 year, int32 month, int32 day) -{ - return _SetDate(year, month, day); -} - - -/*! - This function sets the given \c year, \c month and \c day to the - representative values of this date. The pointers can be NULL. If the date is - invalid, the values will be set to -1 for \c month and \c day, the \c year - will be set to 0. -*/ -void -BDate::GetDate(int32* year, int32* month, int32* day) -{ - if (year) - *year = fYear; - - if (month) - *month = fMonth; - - if (day) - *day = fDay; -} - - -/*! - Adds \c days to the current date. If the passed value is negativ it will - become earlier. If the current date is invalid, the \c days are not added. -*/ -void -BDate::AddDays(int32 days) -{ - if (IsValid()) - *this = JulianDayToDate(DateToJulianDay() + days); -} - - -/*! - Adds \c years to the current date. If the passed value is negativ it will - become earlier. If the current date is invalid, the \c years are not added. - The day/ month combination will be adjusted if it does not exist in the - resulting year, so this function will then return the latest valid date. -*/ -void -BDate::AddYears(int32 years) -{ - if (IsValid()) { - const int32 tmp = fYear; - fYear += years; - - if ((tmp > 0 && fYear <= 0) || (tmp < 0 && fYear >= 0)) - fYear += (years > 0) ? +1 : -1; - - fDay = min_c(fDay, _DaysInMonth(fYear, fMonth)); - } -} - - -/*! - Adds \c months to the current date. If the passed value is negativ it will - become earlier. If the current date is invalid, the \c months are not added. - The day/ month combination will be adjusted if it does not exist in the - resulting year, so this function will then return the latest valid date. -*/ -void -BDate::AddMonths(int32 months) -{ - if (IsValid()) { - const int32 tmp = fYear; - fYear += months / 12; - fMonth += months % 12; - - if (fMonth > 12) { - fYear++; - fMonth -= 12; - } else if (fMonth < 1) { - fYear--; - fMonth += 12; - } - - if ((tmp > 0 && fYear <= 0) || (tmp < 0 && fYear >= 0)) - fYear += (months > 0) ? +1 : -1; - - // 'missing' days between switch julian - gregorian - if (fYear == 1582 && fMonth == 10 && fDay > 4 && fDay < 15) - fDay = (months > 0) ? 15 : 4; - - fDay = min_c(fDay, DaysInMonth()); - } -} - - -/*! - Returns the day fragment of the date. The return value will be in the range - of 1 to 31, in case the date is invalid it will be -1. -*/ -int32 -BDate::Day() const -{ - return fDay; -} - - -/*! - Returns the year fragment of the date. If the date is invalid, the function - returns 0. -*/ -int32 -BDate::Year() const -{ - return fYear; -} - - -/*! - Returns the month fragment of the date. The return value will be in the - range of 1 to 12, in case the date is invalid it will be -1. -*/ -int32 -BDate::Month() const -{ - return fMonth; -} - - -/*! - Returns the difference in days between this date and the given BDate \c date. - If \c date is earlier the return value will be negativ. If the calculation - is done with an invalid date, the result is undefined. -*/ -int32 -BDate::Difference(const BDate& date) const -{ - return date.DateToJulianDay() - DateToJulianDay(); -} - - -/*! - Returns the week number of the date, if the date is invalid it will return - B_ERROR. Please note that this function does only work within the Gregorian - calendar, thus a date before 15.10.1582 will return B_ERROR. -*/ -int32 -BDate::WeekNumber() const -{ - /* - This algorithm is taken from: - Frequently Asked Questions about Calendars - Version 2.8 Claus Tøndering 15 December 2005 - - Note: it will work only within the Gregorian Calendar - */ - - if (!IsValid() || fYear < 1582 - || (fYear == 1582 && fMonth < 10) - || (fYear == 1582 && fMonth == 10 && fDay < 15)) - return int32(B_ERROR); - - int32 a; - int32 b; - int32 s; - int32 e; - int32 f; - - if (fMonth > 0 && fMonth < 3) { - a = fYear - 1; - b = (a / 4) - (a / 100) + (a / 400); - int32 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a -1) / 400); - s = b - c; - e = 0; - f = fDay - 1 + 31 * (fMonth - 1); - } else if (fMonth >= 3 && fMonth <= 12) { - a = fYear; - b = (a / 4) - (a / 100) + (a / 400); - int32 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a -1) / 400); - s = b - c; - e = s + 1; - f = fDay + ((153 * (fMonth - 3) + 2) / 5) + 58 + s; - } else - return int32(B_ERROR); - - int32 g = (a + b) % 7; - int32 d = (f + g - e) % 7; - int32 n = f + 3 - d; - - int32 weekNumber; - if (n < 0) - weekNumber = 53 - (g -s) / 5; - else if (n > 364 + s) - weekNumber = 1; - else - weekNumber = n / 7 + 1; - - return weekNumber; -} - - -/*! - Returns the day of the week in the range of 1 to 7, while 1 stands for - monday. If the date is invalid, the function will return B_ERROR. -*/ -int32 -BDate::DayOfWeek() const -{ - // http://en.wikipedia.org/wiki/Julian_day#Calculation - return IsValid() ? (DateToJulianDay() % 7) + 1 : int32(B_ERROR); -} - - -/*! - Returns the day of the year in the range of 1 to 365 (366 in leap years). If - the date is invalid, the function will return B_ERROR. -*/ -int32 -BDate::DayOfYear() const -{ - if (!IsValid()) - return int32(B_ERROR); - - return DateToJulianDay() - _DateToJulianDay(fYear, 1, 1) + 1; -} - - -/*! - Returns true if the passed \c year is a leap year, otherwise false. If the - \c year passed is before 4713 BC, the result is undefined. -*/ -bool -BDate::IsLeapYear(int32 year) const -{ - if (year < 1582) { - if (year < 0) - year++; - return (year % 4) == 0; - } - return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0); -} - - -/*! - Returns the number of days in the year of the current date. If the date is - valid it will return 365 or 366, otherwise B_ERROR; -*/ -int32 -BDate::DaysInYear() const -{ - if (!IsValid()) - return int32(B_ERROR); - - return IsLeapYear(fYear) ? 366 : 365; -} - - -/*! - Returns the number of days in the month of the current date. If the date is - valid it will return 28 up to 31, otherwise B_ERROR; -*/ -int32 -BDate::DaysInMonth() const -{ - if (!IsValid()) - return int32(B_ERROR); - - return _DaysInMonth(fYear, fMonth); -} - - -/*! - Returns the short day name of this object. -*/ -BString -BDate::ShortDayName() const -{ - return ShortDayName(DayOfWeek()); -} - - -/*! - Returns the short day name in case of an valid day, otherwise an empty - string. The passed \c day must be in the range of 1 to 7 while 1 stands for - monday. -*/ -/*static*/ BString -BDate::ShortDayName(int32 day) -{ - if (day < 1 || day > 7) - return BString(); - - tm tm_struct; - memset(&tm_struct, 0, sizeof(tm)); - tm_struct.tm_wday = day == 7 ? 0 : day; - - char buffer[256]; - strftime(buffer, sizeof(buffer), "%a", &tm_struct); - - return BString(buffer); -} - - -/*! - Returns the short month name of this object. -*/ -BString -BDate::ShortMonthName() const -{ - return ShortMonthName(Month()); -} - - -/*! - Returns the short month name in case of an valid month, otherwise an empty - string. The passed \c month must be in the range of 1 to 12. -*/ -/*static*/ BString -BDate::ShortMonthName(int32 month) -{ - if (month < 1 || month > 12) - return BString(); - - tm tm_struct; - memset(&tm_struct, 0, sizeof(tm)); - tm_struct.tm_mon = month - 1; - - char buffer[256]; - strftime(buffer, sizeof(buffer), "%b", &tm_struct); - - return BString(buffer); -} - - -/*! - Returns the long day name of this object's week day. -*/ -BString -BDate::LongDayName() const -{ - return LongDayName(DayOfWeek()); -} - - -/*! - Returns the long day name in case of an valid day, otherwise an empty - string. The passed \c day must be in the range of 1 to 7 while 1 stands for - monday. -*/ -/*static*/ BString -BDate::LongDayName(int32 day) -{ - if (day < 1 || day > 7) - return BString(); - - tm tm_struct; - memset(&tm_struct, 0, sizeof(tm)); - tm_struct.tm_wday = day == 7 ? 0 : day; - - char buffer[256]; - strftime(buffer, sizeof(buffer), "%A", &tm_struct); - - return BString(buffer); -} - - -/*! - Returns the long month name of this object's month. -*/ -BString -BDate::LongMonthName() const -{ - return LongMonthName(Month()); -} - - -/*! - Returns the long month name in case of an valid month, otherwise an empty - string. The passed \c month must be in the range of 1 to 12. -*/ -/*static*/ BString -BDate::LongMonthName(int32 month) -{ - if (month < 1 || month > 12) - return BString(); - - tm tm_struct; - memset(&tm_struct, 0, sizeof(tm)); - tm_struct.tm_mon = month - 1; - - char buffer[256]; - strftime(buffer, sizeof(buffer), "%B", &tm_struct); - - return BString(buffer); -} - - -/*! - Converts the date to Julian day. If your date is invalid, the function will - return B_ERROR. -*/ -int32 -BDate::DateToJulianDay() const -{ - return _DateToJulianDay(fYear, fMonth, fDay); -} - - -/* - Converts the passed \c julianDay to an BDate. If the \c julianDay is negativ, - the function will return an invalid date. Because of the switch from Julian - calendar to Gregorian calendar the 4.10.1582 is followed by the 15.10.1582. -*/ -BDate -BDate::JulianDayToDate(int32 julianDay) -{ - BDate date; - const int32 kGregorianCalendarStart = 2299161; - if (julianDay >= kGregorianCalendarStart) { - // http://en.wikipedia.org/wiki/Julian_day#Gregorian_calendar_from_Julian_day_number - int32 j = julianDay + 32044; - int32 dg = j % 146097; - int32 c = (dg / 36524 + 1) * 3 / 4; - int32 dc = dg - c * 36524; - int32 db = dc % 1461; - int32 a = (db / 365 + 1) * 3 / 4; - int32 da = db - a * 365; - int32 m = (da * 5 + 308) / 153 - 2; - date.fYear = ((j / 146097) * 400 + c * 100 + (dc / 1461) * 4 + a) - 4800 + - (m + 2) / 12; - date.fMonth = (m + 2) % 12 + 1; - date.fDay = int32((da - (m + 4) * 153 / 5 + 122) + 1.5); - } else if (julianDay >= 0) { - // http://en.wikipedia.org/wiki/Julian_day#Calculation - julianDay += 32082; - int32 d = (4 * julianDay + 3) / 1461; - int32 e = julianDay - (1461 * d) / 4; - int32 m = ((5 * e) + 2) / 153; - date.fDay = e - (153 * m + 2) / 5 + 1; - date.fMonth = m + 3 - 12 * (m / 10); - int32 year = d - 4800 + (m / 10); - if (year <= 0) - year--; - date.fYear = year; - } - return date; -} - - -/*! - Returns true if this date is different from \c date, otherwise false. -*/ -bool -BDate::operator!=(const BDate& date) const -{ - return DateToJulianDay() != date.DateToJulianDay(); -} - - -/*! - Returns true if this date is equal to \c date, otherwise false. -*/ -bool -BDate::operator==(const BDate& date) const -{ - return DateToJulianDay() == date.DateToJulianDay(); -} - - -/*! - Returns true if this date is earlier than \c date, otherwise false. -*/ -bool -BDate::operator<(const BDate& date) const -{ - return DateToJulianDay() < date.DateToJulianDay(); -} - - -/*! - Returns true if this date is earlier than or equal to \c date, otherwise false. -*/ -bool -BDate::operator<=(const BDate& date) const -{ - return DateToJulianDay() <= date.DateToJulianDay(); -} - - -/*! - Returns true if this date is later than \c date, otherwise false. -*/ -bool -BDate::operator>(const BDate& date) const -{ - return DateToJulianDay() > date.DateToJulianDay(); -} - - -/*! - Returns true if this date is later than or equal to \c date, otherwise false. -*/ -bool -BDate::operator>=(const BDate& date) const -{ - return DateToJulianDay() >= date.DateToJulianDay(); -} - - -bool -BDate::_SetDate(int32 year, int32 month, int32 day) -{ - fDay = -1; - fYear = 0; - fMonth = -1; - - bool valid = IsValid(year, month, day); - if (valid) { - fDay = day; - fYear = year; - fMonth = month; - } - - return valid; -} - - -int32 -BDate::_DaysInMonth(int32 year, int32 month) const -{ - if (month == 2 && IsLeapYear(year)) - return 29; - - const int32 daysInMonth[12] = - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - - return daysInMonth[month -1]; -} - - -int32 -BDate::_DateToJulianDay(int32 _year, int32 month, int32 day) const -{ - if (IsValid(_year, month, day)) { - int32 year = _year; - if (year < 0) year++; - - int32 a = (14 - month) / 12; - int32 y = year + 4800 - a; - int32 m = month + (12 * a) - 3; - - // http://en.wikipedia.org/wiki/Julian_day#Calculation - if (year > 1582 - || (year == 1582 && month > 10) - || (year == 1582 && month == 10 && day >= 15)) { - return day + (((153 * m) + 2) / 5) + (365 * y) + (y / 4) - - (y / 100) + (y / 400) - 32045; - } else if (year < 1582 - || (year == 1582 && month < 10) - || (year == 1582 && month == 10 && day <= 4)) { - return day + (((153 * m) + 2) / 5) + (365 * y) + (y / 4) - 32083; - } - } - - // http://en.wikipedia.org/wiki/Gregorian_calendar: - // The last day of the Julian calendar was Thursday October 4, 1582 - // and this was followed by the first day of the Gregorian calendar, - // Friday October 15, 1582 (the cycle of weekdays was not affected). - return int32(B_ERROR); -} - - -// #pragma mark - BDateTime - - -/*! - Constructs a new BDateTime object. IsValid() will return false. -*/ -BDateTime::BDateTime() - : fDate(), - fTime() -{ -} - - -/*! - Constructs a BDateTime object with \c date and \c time. The return value - of IsValid() depends on the validity of the passed objects. -*/ -BDateTime::BDateTime(const BDate& date, const BTime& time) - : fDate(date), - fTime(time) -{ -} - - -/*! - Constructs a new BDateTime object. IsValid() will return false. -*/ -BDateTime::BDateTime(const BMessage* archive) - : fDate(archive), - fTime(archive) -{ -} - - -/*! - Empty destructor. -*/ -BDateTime::~BDateTime() -{ -} - - -/*! - Archives the BDateTime object into the provided BMessage object. - @returns \c B_OK if all went well. - \c B_BAD_VALUE, if the message is \c NULL. - \c other error codes, depending on failure to append - fields to the message. -*/ -status_t -BDateTime::Archive(BMessage* into) const -{ - status_t ret = fDate.Archive(into); - if (ret == B_OK) - ret = fTime.Archive(into); - return ret; -} - - -/*! - Returns true if the date time is valid, otherwise false. -*/ -bool -BDateTime::IsValid() const -{ - return fDate.IsValid() && fTime.IsValid(); -} - - -/*! - Returns the current date and time as reported by the system depending on the - given time_type \c type. -*/ -BDateTime -BDateTime::CurrentDateTime(time_type type) -{ - return BDateTime(BDate::CurrentDate(type), BTime::CurrentTime(type)); -} - - -/*! - Sets the current date and time of this object to \c date and \c time. -*/ -void -BDateTime::SetDateTime(const BDate& date, const BTime& time) -{ - fDate = date; - fTime = time; -} - - -/*! - Returns the current date of this object. -*/ -BDate& -BDateTime::Date() -{ - return fDate; -} - - -/*! - Returns the current date of this object. -*/ -const BDate& -BDateTime::Date() const -{ - return fDate; -} - - -/*! - Set the current date of this object to \c date. -*/ -void -BDateTime::SetDate(const BDate& date) -{ - fDate = date; -} - - -/*! - Returns the current time of this object. -*/ -BTime& -BDateTime::Time() -{ - return fTime; -} - - -/*! - Returns the current time of this object. -*/ -const BTime& -BDateTime::Time() const -{ - return fTime; -} - - -/*! - Sets the current time of this object to \c time. -*/ -void -BDateTime::SetTime(const BTime& time) -{ - fTime = time; -} - - -/*! - Returns the current date and time converted to seconds since - 1.1.1970 - 00:00:00. If the current date is before 1.1.1970 the function - returns -1; -*/ -int32 -BDateTime::Time_t() const -{ - BDate date(1970, 1, 1); - if (date.Difference(fDate) < 0) - return -1; - - tm tm_struct; - - tm_struct.tm_hour = fTime.Hour(); - tm_struct.tm_min = fTime.Minute(); - tm_struct.tm_sec = fTime.Second(); - - tm_struct.tm_year = fDate.Year() - 1900; - tm_struct.tm_mon = fDate.Month() - 1; - tm_struct.tm_mday = fDate.Day(); - - // set less 0 as we wan't use it - tm_struct.tm_isdst = -1; - - // return secs_since_jan1_1970 or -1 on error - return int32(mktime(&tm_struct)); -} - - -/*! - Sets the current date and time converted from seconds since - 1.1.1970 - 00:00:00. -*/ -void -BDateTime::SetTime_t(uint32 seconds) -{ - BTime time; - time.AddSeconds(seconds % kSecondsPerDay); - fTime.SetTime(time); - - BDate date(1970, 1, 1); - date.AddDays(seconds / kSecondsPerDay); - fDate.SetDate(date); -} - - -/*! - Returns true if this datetime is different from \c dateTime, otherwise false. -*/ -bool -BDateTime::operator!=(const BDateTime& dateTime) const -{ - return fTime != dateTime.fTime && fDate != dateTime.fDate; -} - - -/*! - Returns true if this datetime is equal to \c dateTime, otherwise false. -*/ -bool -BDateTime::operator==(const BDateTime& dateTime) const -{ - return fTime == dateTime.fTime && fDate == dateTime.fDate; -} - - -/*! - Returns true if this datetime is earlier than \c dateTime, otherwise false. -*/ -bool -BDateTime::operator<(const BDateTime& dateTime) const -{ - if (fDate < dateTime.fDate) - return true; - if (fDate == dateTime.fDate) - return fTime < dateTime.fTime; - return false; -} - - -/*! - Returns true if this datetime is earlier than or equal to \c dateTime, - otherwise false. -*/ -bool -BDateTime::operator<=(const BDateTime& dateTime) const -{ - if (fDate < dateTime.fDate) - return true; - if (fDate == dateTime.fDate) - return fTime <= dateTime.fTime; - return false; -} - - -/*! - Returns true if this datetime is later than \c dateTime, otherwise false. -*/ -bool -BDateTime::operator>(const BDateTime& dateTime) const -{ - if (fDate > dateTime.fDate) - return true; - if (fDate == dateTime.fDate) - return fTime > dateTime.fTime; - return false; -} - - -/*! - Returns true if this datetime is later than or equal to \c dateTime, - otherwise false. -*/ -bool -BDateTime::operator>=(const BDateTime& dateTime) const -{ - if (fDate > dateTime.fDate) - return true; - if (fDate == dateTime.fDate) - return fTime >= dateTime.fTime; - return false; -} - - -} //namespace BPrivate diff --git a/src/apps/webpositive/support/DateTime.h b/src/apps/webpositive/support/DateTime.h deleted file mode 100644 index 93f76399d6..0000000000 --- a/src/apps/webpositive/support/DateTime.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2007-2010, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _DATE_TIME_H_ -#define _DATE_TIME_H_ - - -#include - - -class BMessage; - - -namespace BPrivate { - - -enum time_type { - B_GMT_TIME, - B_LOCAL_TIME -}; - - -enum diff_type { - B_HOURS_DIFF, - B_MINUTES_DIFF, - B_SECONDS_DIFF, - B_MILLISECONDS_DIFF, - B_MICROSECONDS_DIFF -}; - - -class BTime { -public: - BTime(); - BTime(const BTime& other); - BTime(int32 hour, int32 minute, int32 second, - int32 microsecond = 0); - BTime(const BMessage* archive); - ~BTime(); - - status_t Archive(BMessage* into) const; - - bool IsValid() const; - bool IsValid(const BTime& time) const; - bool IsValid(int32 hour, int32 minute, int32 second, - int32 microsecond = 0) const; - - static BTime CurrentTime(time_type type); - - BTime Time() const; - bool SetTime(const BTime& time); - bool SetTime(int32 hour, int32 minute, int32 second, - int32 microsecond = 0); - - BTime& AddHours(int32 hours); - BTime& AddMinutes(int32 minutes); - BTime& AddSeconds(int32 seconds); - BTime& AddMilliseconds(int32 milliseconds); - BTime& AddMicroseconds(int32 microseconds); - - int32 Hour() const; - int32 Minute() const; - int32 Second() const; - int32 Millisecond() const; - int32 Microsecond() const; - bigtime_t Difference(const BTime& time, - diff_type type) const; - - bool operator!=(const BTime& time) const; - bool operator==(const BTime& time) const; - - bool operator<(const BTime& time) const; - bool operator<=(const BTime& time) const; - - bool operator>(const BTime& time) const; - bool operator>=(const BTime& time) const; - -private: - bigtime_t _Microseconds() const; - BTime& _AddMicroseconds(bigtime_t microseconds); - bool _SetTime(bigtime_t hour, bigtime_t minute, - bigtime_t second, bigtime_t microsecond); - -private: - bigtime_t fMicroseconds; -}; - - -class BDate { -public: - BDate(); - BDate(const BDate& other); - BDate(int32 year, int32 month, int32 day); - BDate(const BMessage* archive); - ~BDate(); - - status_t Archive(BMessage* into) const; - - bool IsValid() const; - bool IsValid(const BDate& date) const; - bool IsValid(int32 year, int32 month, - int32 day) const; - - static BDate CurrentDate(time_type type); - - BDate Date() const; - bool SetDate(const BDate& date); - - bool SetDate(int32 year, int32 month, int32 day); - void GetDate(int32* year, int32* month, int32* day); - - void AddDays(int32 days); - void AddYears(int32 years); - void AddMonths(int32 months); - - int32 Day() const; - int32 Year() const; - int32 Month() const; - int32 Difference(const BDate& date) const; - - int32 DayOfWeek() const; - int32 DayOfYear() const; - - int32 WeekNumber() const; - bool IsLeapYear(int32 year) const; - - int32 DaysInYear() const; - int32 DaysInMonth() const; - - BString ShortDayName() const; - static BString ShortDayName(int32 day); - - BString ShortMonthName() const; - static BString ShortMonthName(int32 month); - - BString LongDayName() const; - static BString LongDayName(int32 day); - - BString LongMonthName() const; - static BString LongMonthName(int32 month); - - int32 DateToJulianDay() const; - static BDate JulianDayToDate(int32 julianDay); - - bool operator!=(const BDate& date) const; - bool operator==(const BDate& date) const; - - bool operator<(const BDate& date) const; - bool operator<=(const BDate& date) const; - - bool operator>(const BDate& date) const; - bool operator>=(const BDate& date) const; - -private: - int32 _DaysInMonth(int32 year, int32 month) const; - bool _SetDate(int32 year, int32 month, int32 day); - int32 _DateToJulianDay(int32 year, int32 month, - int32 day) const; - -private: - int32 fDay; - int32 fYear; - int32 fMonth; -}; - - -class BDateTime { -public: - BDateTime(); - BDateTime(const BDate &date, const BTime &time); - BDateTime(const BMessage* archive); - ~BDateTime(); - - status_t Archive(BMessage* into) const; - - bool IsValid() const; - - static BDateTime CurrentDateTime(time_type type); - void SetDateTime(const BDate &date, const BTime &time); - - BDate& Date(); - const BDate& Date() const; - void SetDate(const BDate &date); - - BTime& Time(); - const BTime& Time() const; - void SetTime(const BTime &time); - - int32 Time_t() const; - void SetTime_t(uint32 seconds); - - bool operator!=(const BDateTime& dateTime) const; - bool operator==(const BDateTime& dateTime) const; - - bool operator<(const BDateTime& dateTime) const; - bool operator<=(const BDateTime& dateTime) const; - - bool operator>(const BDateTime& dateTime) const; - bool operator>=(const BDateTime& dateTime) const; - -private: - BDate fDate; - BTime fTime; -}; - - -} // namespace BPrivate - - -using BPrivate::time_type; -using BPrivate::B_GMT_TIME; -using BPrivate::B_LOCAL_TIME; -using BPrivate::diff_type; -using BPrivate::B_HOURS_DIFF; -using BPrivate::B_MINUTES_DIFF; -using BPrivate::B_SECONDS_DIFF; -using BPrivate::B_MILLISECONDS_DIFF; -using BPrivate::B_MICROSECONDS_DIFF; -using BPrivate::BTime; -using BPrivate::BDate; -using BPrivate::BDateTime; - - -#endif // _DATE_TIME_H_ diff --git a/src/apps/webpositive/support/HashMap.h b/src/apps/webpositive/support/HashMap.h deleted file mode 100644 index 36b321f2b8..0000000000 --- a/src/apps/webpositive/support/HashMap.h +++ /dev/null @@ -1,481 +0,0 @@ -// HashMap.h -// -// Copyright (c) 2004-2007, Ingo Weinhold (bonefish@cs.tu-berlin.de) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// 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. - -#ifndef HASH_MAP_H -#define HASH_MAP_H - - -#include - -#include "AutoLocker.h" -#include "OpenHashTable.h" - - -namespace BPrivate { - -// HashMapElement -template -class HashMapElement : public OpenHashElement { -private: - typedef HashMapElement Element; -public: - - HashMapElement() : OpenHashElement(), fKey(), fValue() - { - fNext = -1; - } - - inline uint32 Hash() const - { - return fKey.GetHashCode(); - } - - inline bool operator==(const OpenHashElement &_element) const - { - const Element &element = static_cast(_element); - return (fKey == element.fKey); - } - - inline void Adopt(Element &element) - { - fKey = element.fKey; - fValue = element.fValue; - } - - Key fKey; - Value fValue; -}; - -// HashMap -template -class HashMap { -public: - class Entry { - public: - Entry() {} - Entry(const Key& key, Value value) : key(key), value(value) {} - - Key key; - Value value; - }; - - class Iterator { - private: - typedef HashMapElement Element; - public: - Iterator(const Iterator& other) - : - fMap(other.fMap), - fIndex(other.fIndex), - fElement(other.fElement), - fLastElement(other.fElement) - { - } - - bool HasNext() const - { - return fElement; - } - - Entry Next() - { - if (!fElement) - return Entry(); - Entry result(fElement->fKey, fElement->fValue); - _FindNext(); - return result; - } - - Value* NextValue() - { - if (fElement == NULL) - return NULL; - - Value* value = &fElement->fValue; - _FindNext(); - return value; - } - - Entry Remove() - { - if (!fLastElement) - return Entry(); - Entry result(fLastElement->fKey, fLastElement->fValue); - fMap->fTable.Remove(fLastElement, true); - fLastElement = NULL; - return result; - } - - Iterator& operator=(const Iterator& other) - { - fMap = other.fMap; - fIndex = other.fIndex; - fElement = other.fElement; - fLastElement = other.fLastElement; - return *this; - } - - private: - Iterator(const HashMap* map) - : - fMap(const_cast*>(map)), - fIndex(0), - fElement(NULL), - fLastElement(NULL) - { - // find first - _FindNext(); - } - - void _FindNext() - { - fLastElement = fElement; - if (fElement && fElement->fNext >= 0) { - fElement = fMap->fTable.ElementAt(fElement->fNext); - return; - } - fElement = NULL; - int32 arraySize = fMap->fTable.ArraySize(); - for (; !fElement && fIndex < arraySize; fIndex++) - fElement = fMap->fTable.FindFirst(fIndex); - } - - private: - friend class HashMap; - - HashMap* fMap; - int32 fIndex; - Element* fElement; - Element* fLastElement; - }; - - HashMap(); - ~HashMap(); - - status_t InitCheck() const; - - status_t Put(const Key& key, Value value); - Value Remove(const Key& key); - void Clear(); - Value Get(const Key& key) const; - bool Get(const Key& key, Value*& _value) const; - - bool ContainsKey(const Key& key) const; - - int32 Size() const; - - Iterator GetIterator() const; - -protected: - typedef HashMapElement Element; - friend class Iterator; - -private: - Element *_FindElement(const Key& key) const; - -protected: - OpenHashElementArray fElementArray; - OpenHashTable > fTable; -}; - -// SynchronizedHashMap -template -class SynchronizedHashMap : public BLocker { -public: - typedef struct HashMap::Entry Entry; - typedef struct HashMap::Iterator Iterator; - - SynchronizedHashMap() : BLocker("synchronized hash map") {} - ~SynchronizedHashMap() { Lock(); } - - status_t InitCheck() const - { - return fMap.InitCheck(); - } - - status_t Put(const Key& key, Value value) - { - MapLocker locker(this); - if (!locker.IsLocked()) - return B_ERROR; - return fMap.Put(key, value); - } - - Value Remove(const Key& key) - { - MapLocker locker(this); - if (!locker.IsLocked()) - return Value(); - return fMap.Remove(key); - } - - void Clear() - { - MapLocker locker(this); - return fMap.Clear(); - } - - Value Get(const Key& key) const - { - const BLocker* lock = this; - MapLocker locker(const_cast(lock)); - if (!locker.IsLocked()) - return Value(); - return fMap.Get(key); - } - - bool ContainsKey(const Key& key) const - { - const BLocker* lock = this; - MapLocker locker(const_cast(lock)); - if (!locker.IsLocked()) - return false; - return fMap.ContainsKey(key); - } - - int32 Size() const - { - const BLocker* lock = this; - MapLocker locker(const_cast(lock)); - return fMap.Size(); - } - - Iterator GetIterator() - { - return fMap.GetIterator(); - } - - // for debugging only - const HashMap& GetUnsynchronizedMap() const { return fMap; } - HashMap& GetUnsynchronizedMap() { return fMap; } - -protected: - typedef AutoLocker MapLocker; - - HashMap fMap; -}; - -// HashKey32 -template -struct HashKey32 { - HashKey32() {} - HashKey32(const Value& value) : value(value) {} - - uint32 GetHashCode() const - { - return (uint32)value; - } - - HashKey32 operator=(const HashKey32& other) - { - value = other.value; - return *this; - } - - bool operator==(const HashKey32& other) const - { - return (value == other.value); - } - - bool operator!=(const HashKey32& other) const - { - return (value != other.value); - } - - Value value; -}; - - -// HashKey64 -template -struct HashKey64 { - HashKey64() {} - HashKey64(const Value& value) : value(value) {} - - uint32 GetHashCode() const - { - uint64 v = (uint64)value; - return (uint32)(v >> 32) ^ (uint32)v; - } - - HashKey64 operator=(const HashKey64& other) - { - value = other.value; - return *this; - } - - bool operator==(const HashKey64& other) const - { - return (value == other.value); - } - - bool operator!=(const HashKey64& other) const - { - return (value != other.value); - } - - Value value; -}; - - -// HashMap - -// constructor -template -HashMap::HashMap() - : - fElementArray(1000), - fTable(1000, &fElementArray) -{ -} - -// destructor -template -HashMap::~HashMap() -{ -} - -// InitCheck -template -status_t -HashMap::InitCheck() const -{ - return (fTable.InitCheck() && fElementArray.InitCheck() - ? B_OK : B_NO_MEMORY); -} - -// Put -template -status_t -HashMap::Put(const Key& key, Value value) -{ - Element* element = _FindElement(key); - if (element) { - // already contains the key: just set the new value - element->fValue = value; - return B_OK; - } - // does not contain the key yet: add an element - element = fTable.Add(key.GetHashCode()); - if (!element) - return B_NO_MEMORY; - element->fKey = key; - element->fValue = value; - return B_OK; -} - -// Remove -template -Value -HashMap::Remove(const Key& key) -{ - Value value = Value(); - if (Element* element = _FindElement(key)) { - value = element->fValue; - fTable.Remove(element); - } - return value; -} - -// Clear -template -void -HashMap::Clear() -{ - fTable.RemoveAll(); -} - -// Get -template -Value -HashMap::Get(const Key& key) const -{ - if (Element* element = _FindElement(key)) - return element->fValue; - return Value(); -} - -// Get -template -bool -HashMap::Get(const Key& key, Value*& _value) const -{ - if (Element* element = _FindElement(key)) { - _value = &element->fValue; - return true; - } - - return false; -} - -// ContainsKey -template -bool -HashMap::ContainsKey(const Key& key) const -{ - return _FindElement(key); -} - -// Size -template -int32 -HashMap::Size() const -{ - return fTable.CountElements(); -} - -// GetIterator -template -struct HashMap::Iterator -HashMap::GetIterator() const -{ - return Iterator(this); -} - -// _FindElement -template -struct HashMap::Element * -HashMap::_FindElement(const Key& key) const -{ - Element* element = fTable.FindFirst(key.GetHashCode()); - while (element && element->fKey != key) { - if (element->fNext >= 0) - element = fTable.ElementAt(element->fNext); - else - element = NULL; - } - return element; -} - -} // namespace BPrivate - -using BPrivate::HashMap; -using BPrivate::HashKey32; -using BPrivate::HashKey64; -using BPrivate::SynchronizedHashMap; - -#endif // HASH_MAP_H diff --git a/src/apps/webpositive/support/HashSet.h b/src/apps/webpositive/support/HashSet.h deleted file mode 100644 index ee7be71288..0000000000 --- a/src/apps/webpositive/support/HashSet.h +++ /dev/null @@ -1,342 +0,0 @@ -// HashSet.h -// -// Copyright (c) 2004, Ingo Weinhold (bonefish@cs.tu-berlin.de) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// 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. - -#ifndef HASH_SET_H -#define HASH_SET_H - -#include - -#include "AutoLocker.h" -#include "OpenHashTable.h" - - -namespace BPrivate { - -// HashSetElement -template -class HashSetElement : public OpenHashElement { -private: - typedef HashSetElement Element; -public: - - HashSetElement() : OpenHashElement(), fKey() - { - fNext = -1; - } - - inline uint32 Hash() const - { - return fKey.GetHashCode(); - } - - inline bool operator==(const OpenHashElement &_element) const - { - const Element &element = static_cast(_element); - return (fKey == element.fKey); - } - - inline void Adopt(Element &element) - { - fKey = element.fKey; - } - - Key fKey; -}; - -// HashSet -template -class HashSet { -public: - class Iterator { - private: - typedef HashSetElement Element; - public: - Iterator(const Iterator& other) - : fSet(other.fSet), - fIndex(other.fIndex), - fElement(other.fElement), - fLastElement(other.fElement) - { - } - - bool HasNext() const - { - return fElement; - } - - Key Next() - { - if (!fElement) - return Key(); - Key result(fElement->fKey); - _FindNext(); - return result; - } - - bool Remove() - { - if (!fLastElement) - return false; - fSet->fTable.Remove(fLastElement); - fLastElement = NULL; - return true; - } - - Iterator& operator=(const Iterator& other) - { - fSet = other.fSet; - fIndex = other.fIndex; - fElement = other.fElement; - fLastElement = other.fLastElement; - return *this; - } - - private: - Iterator(HashSet* map) - : fSet(map), - fIndex(0), - fElement(NULL), - fLastElement(NULL) - { - // find first - _FindNext(); - } - - void _FindNext() - { - fLastElement = fElement; - if (fElement && fElement->fNext >= 0) { - fElement = fSet->fTable.ElementAt(fElement->fNext); - return; - } - fElement = NULL; - int32 arraySize = fSet->fTable.ArraySize(); - for (; !fElement && fIndex < arraySize; fIndex++) - fElement = fSet->fTable.FindFirst(fIndex); - } - - private: - friend class HashSet; - - HashSet* fSet; - int32 fIndex; - Element* fElement; - Element* fLastElement; - }; - - HashSet(); - ~HashSet(); - - status_t InitCheck() const; - - status_t Add(const Key& key); - bool Remove(const Key& key); - void Clear(); - bool Contains(const Key& key) const; - - int32 Size() const; - bool IsEmpty() const { return Size() == 0; } - - Iterator GetIterator(); - -protected: - typedef HashSetElement Element; - friend class Iterator; - -private: - Element *_FindElement(const Key& key) const; - -protected: - OpenHashElementArray fElementArray; - OpenHashTable > fTable; -}; - -// SynchronizedHashSet -template -class SynchronizedHashSet : public BLocker { -public: - typedef struct HashSet::Iterator Iterator; - - SynchronizedHashSet() : BLocker("synchronized hash set") {} - ~SynchronizedHashSet() { Lock(); } - - status_t InitCheck() const - { - return fSet.InitCheck(); - } - - status_t Add(const Key& key) - { - MapLocker locker(this); - if (!locker.IsLocked()) - return B_ERROR; - return fSet.Add(key); - } - - bool Remove(const Key& key) - { - MapLocker locker(this); - if (!locker.IsLocked()) - return false; - return fSet.Remove(key); - } - - bool Contains(const Key& key) const - { - const BLocker* lock = this; - MapLocker locker(const_cast(lock)); - if (!locker.IsLocked()) - return false; - return fSet.Contains(key); - } - - int32 Size() const - { - const BLocker* lock = this; - MapLocker locker(const_cast(lock)); - return fSet.Size(); - } - - Iterator GetIterator() - { - return fSet.GetIterator(); - } - - // for debugging only - const HashSet& GetUnsynchronizedSet() const { return fSet; } - HashSet& GetUnsynchronizedSet() { return fSet; } - -protected: - typedef AutoLocker MapLocker; - - HashSet fSet; -}; - -// HashSet - -// constructor -template -HashSet::HashSet() - : fElementArray(1000), - fTable(1000, &fElementArray) -{ -} - -// destructor -template -HashSet::~HashSet() -{ -} - -// InitCheck -template -status_t -HashSet::InitCheck() const -{ - return (fTable.InitCheck() && fElementArray.InitCheck() - ? B_OK : B_NO_MEMORY); -} - -// Add -template -status_t -HashSet::Add(const Key& key) -{ - if (Contains(key)) - return B_OK; - Element* element = fTable.Add(key.GetHashCode()); - if (!element) - return B_NO_MEMORY; - element->fKey = key; - return B_OK; -} - -// Remove -template -bool -HashSet::Remove(const Key& key) -{ - if (Element* element = _FindElement(key)) { - fTable.Remove(element); - return true; - } - return false; -} - -// Clear -template -void -HashSet::Clear() -{ - fTable.RemoveAll(); -} - -// Contains -template -bool -HashSet::Contains(const Key& key) const -{ - return _FindElement(key); -} - -// Size -template -int32 -HashSet::Size() const -{ - return fTable.CountElements(); -} - -// GetIterator -template -struct HashSet::Iterator -HashSet::GetIterator() -{ - return Iterator(this); -} - -// _FindElement -template -struct HashSet::Element * -HashSet::_FindElement(const Key& key) const -{ - Element* element = fTable.FindFirst(key.GetHashCode()); - while (element && element->fKey != key) { - if (element->fNext >= 0) - element = fTable.ElementAt(element->fNext); - else - element = NULL; - } - return element; -} - -} // namespace BPrivate - -using BPrivate::HashSet; -using BPrivate::SynchronizedHashSet; - -#endif // HASH_SET_H diff --git a/src/apps/webpositive/support/IconButton.cpp b/src/apps/webpositive/support/IconButton.cpp deleted file mode 100644 index 5cd2ede604..0000000000 --- a/src/apps/webpositive/support/IconButton.cpp +++ /dev/null @@ -1,929 +0,0 @@ -/* - * Copyright 2006-2010, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Stephan Aßmus - */ - -// NOTE: this file is a duplicate of the version in Icon-O-Matic/generic -// it should be placed into a common folder for generic useful stuff - -#include "IconButton.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "IconUtils.h" - -using std::nothrow; - -// constructor -IconButton::IconButton(const char* name, uint32 id, const char* label, - BMessage* message, BHandler* target) - : BView(name, B_WILL_DRAW), - BInvoker(message, target), - fButtonState(STATE_ENABLED), - fID(id), - fNormalBitmap(NULL), - fDisabledBitmap(NULL), - fClickedBitmap(NULL), - fDisabledClickedBitmap(NULL), - fLabel(label), - fTargetCache(target) -{ - SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - SetViewColor(B_TRANSPARENT_32_BIT); -} - -// destructor -IconButton::~IconButton() -{ - _DeleteBitmaps(); -} - -// MessageReceived -void -IconButton::MessageReceived(BMessage* message) -{ - switch (message->what) { - default: - BView::MessageReceived(message); - break; - } -} - -// AttachedToWindow -void -IconButton::AttachedToWindow() -{ - rgb_color background = B_TRANSPARENT_COLOR; - if (BView* parent = Parent()) { - background = parent->ViewColor(); - if (background == B_TRANSPARENT_COLOR) - background = parent->LowColor(); - } - if (background == B_TRANSPARENT_COLOR) - background = ui_color(B_PANEL_BACKGROUND_COLOR); - SetLowColor(background); - - SetTarget(fTargetCache); - if (!Target()) - SetTarget(Window()); -} - -// Draw -void -IconButton::Draw(BRect area) -{ - rgb_color background = LowColor(); - - BRect r(Bounds()); - - if (be_control_look != NULL) { - uint32 flags = 0; - BBitmap* bitmap = fNormalBitmap; - if (!IsEnabled()) { - flags |= BControlLook::B_DISABLED; - bitmap = fDisabledBitmap; - } - if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) - flags |= BControlLook::B_ACTIVATED; - - if (DrawBorder()) { - be_control_look->DrawButtonFrame(this, r, area, background, - background, flags); - be_control_look->DrawButtonBackground(this, r, area, background, - flags); - } else { - SetHighColor(background); - FillRect(r); - } - - if (bitmap && bitmap->IsValid()) { - float x = r.left + floorf((r.Width() - - bitmap->Bounds().Width()) / 2.0 + 0.5); - float y = r.top + floorf((r.Height() - - bitmap->Bounds().Height()) / 2.0 + 0.5); - BPoint point(x, y); - if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) - point += BPoint(1.0, 1.0); - if (bitmap->ColorSpace() == B_RGBA32 - || bitmap->ColorSpace() == B_RGBA32_BIG) { - SetDrawingMode(B_OP_ALPHA); - SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); - } - DrawBitmap(bitmap, point); - } - return; - } - - rgb_color lightShadow, shadow, darkShadow, light; - BBitmap* bitmap = fNormalBitmap; - // adjust colors and bitmap according to flags - if (IsEnabled()) { - lightShadow = tint_color(background, B_DARKEN_1_TINT); - shadow = tint_color(background, B_DARKEN_2_TINT); - darkShadow = tint_color(background, B_DARKEN_4_TINT); - light = tint_color(background, B_LIGHTEN_MAX_TINT); - SetHighColor(0, 0, 0, 255); - } else { - lightShadow = tint_color(background, 1.11); - shadow = tint_color(background, B_DARKEN_1_TINT); - darkShadow = tint_color(background, B_DARKEN_2_TINT); - light = tint_color(background, B_LIGHTEN_2_TINT); - bitmap = fDisabledBitmap; - SetHighColor(tint_color(background, B_DISABLED_LABEL_TINT)); - } - if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) { - if (IsEnabled()) { -// background = tint_color(background, B_DARKEN_2_TINT); -// background = tint_color(background, B_LIGHTEN_1_TINT); - background = tint_color(background, B_DARKEN_1_TINT); - bitmap = fClickedBitmap; - } else { -// background = tint_color(background, B_DARKEN_1_TINT); -// background = tint_color(background, (B_NO_TINT + B_LIGHTEN_1_TINT) / 2.0); - background = tint_color(background, (B_NO_TINT + B_DARKEN_1_TINT) / 2.0); - bitmap = fDisabledClickedBitmap; - } - // background - SetLowColor(background); - r.InsetBy(2.0, 2.0); - StrokeLine(r.LeftBottom(), r.LeftTop(), B_SOLID_LOW); - StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_LOW); - r.InsetBy(-2.0, -2.0); - } - // draw frame only if tracking - if (DrawBorder()) { - if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) - DrawPressedBorder(r, background, shadow, darkShadow, lightShadow, light); - else - DrawNormalBorder(r, background, shadow, darkShadow, lightShadow, light); - r.InsetBy(2.0, 2.0); - } else - _DrawFrame(r, background, background, background, background); - float width = Bounds().Width(); - float height = Bounds().Height(); - // bitmap - BRegion originalClippingRegion; - if (bitmap && bitmap->IsValid()) { - float x = floorf((width - bitmap->Bounds().Width()) / 2.0 + 0.5); - float y = floorf((height - bitmap->Bounds().Height()) / 2.0 + 0.5); - BPoint point(x, y); - if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) - point += BPoint(1.0, 1.0); - if (bitmap->ColorSpace() == B_RGBA32 || bitmap->ColorSpace() == B_RGBA32_BIG) { - FillRect(r, B_SOLID_LOW); - SetDrawingMode(B_OP_ALPHA); - SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); - } - DrawBitmap(bitmap, point); - // constrain clipping region - BRegion region= originalClippingRegion; - GetClippingRegion(®ion); - region.Exclude(bitmap->Bounds().OffsetByCopy(point)); - ConstrainClippingRegion(®ion); - } - // background - SetDrawingMode(B_OP_COPY); - FillRect(r, B_SOLID_LOW); - ConstrainClippingRegion(NULL); - // label - if (fLabel.CountChars() > 0) { - SetDrawingMode(B_OP_COPY); - font_height fh; - GetFontHeight(&fh); - float y = Bounds().bottom - 4.0; - y -= fh.descent; - float x = (width - StringWidth(fLabel.String())) / 2.0; - DrawString(fLabel.String(), BPoint(x, y)); - } -} - -// MouseDown -void -IconButton::MouseDown(BPoint where) -{ - if (!IsValid()) - return; - - if (_HasFlags(STATE_ENABLED)/* && !_HasFlags(STATE_FORCE_PRESSED)*/) { - if (Bounds().Contains(where)) { - SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); - _AddFlags(STATE_PRESSED | STATE_TRACKING); - } else { - _ClearFlags(STATE_PRESSED | STATE_TRACKING); - } - } -} - -// MouseUp -void -IconButton::MouseUp(BPoint where) -{ - if (!IsValid()) - return; - -// if (!_HasFlags(STATE_FORCE_PRESSED)) { - if (_HasFlags(STATE_ENABLED) && _HasFlags(STATE_PRESSED) && Bounds().Contains(where)) - Invoke(); - else if (Bounds().Contains(where)) - _AddFlags(STATE_INSIDE); - _ClearFlags(STATE_PRESSED | STATE_TRACKING); -// } -} - -// MouseMoved -void -IconButton::MouseMoved(BPoint where, uint32 transit, const BMessage* message) -{ - if (!IsValid()) - return; - - uint32 buttons = 0; - Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); - // catch a mouse up event that we might have missed - if (!buttons && _HasFlags(STATE_PRESSED)) { - MouseUp(where); - return; - } - if (buttons && !_HasFlags(STATE_TRACKING)) - return; - if ((transit == B_INSIDE_VIEW || transit == B_ENTERED_VIEW) - && _HasFlags(STATE_ENABLED)) - _AddFlags(STATE_INSIDE); - else - _ClearFlags(STATE_INSIDE); - if (_HasFlags(STATE_TRACKING)) { - if (Bounds().Contains(where)) - _AddFlags(STATE_PRESSED); - else - _ClearFlags(STATE_PRESSED); - } -} - -#define MIN_SPACE 15.0 - -// GetPreferredSize -void -IconButton::GetPreferredSize(float* width, float* height) -{ - float minWidth = 0.0; - float minHeight = 0.0; - if (IsValid()) { - minWidth += fNormalBitmap->Bounds().IntegerWidth() + 1.0; - minHeight += fNormalBitmap->Bounds().IntegerHeight() + 1.0; - } - if (minWidth < MIN_SPACE) - minWidth = MIN_SPACE; - if (minHeight < MIN_SPACE) - minHeight = MIN_SPACE; - - float hPadding = max_c(6.0, ceilf(minHeight / 4.0)); - float vPadding = max_c(6.0, ceilf(minWidth / 4.0)); - - if (fLabel.CountChars() > 0) { - font_height fh; - GetFontHeight(&fh); - minHeight += ceilf(fh.ascent + fh.descent) + vPadding; - minWidth += StringWidth(fLabel.String()) + vPadding; - } - - if (width) - *width = minWidth + hPadding; - if (height) - *height = minHeight + vPadding; -} - -// MinSize -BSize -IconButton::MinSize() -{ - BSize size; - GetPreferredSize(&size.width, &size.height); - return size; -} - -// MaxSize -BSize -IconButton::MaxSize() -{ - return MinSize(); -} - -// Invoke -status_t -IconButton::Invoke(BMessage* message) -{ - if (!message) - message = Message(); - if (message) { - BMessage clone(*message); - clone.AddInt64("be:when", system_time()); - clone.AddPointer("be:source", (BView*)this); - clone.AddInt32("be:value", Value()); - clone.AddInt32("id", ID()); - return BInvoker::Invoke(&clone); - } - return BInvoker::Invoke(message); -} - -// SetPressed -void -IconButton::SetPressed(bool pressed) -{ - if (pressed) - _AddFlags(STATE_FORCE_PRESSED); - else - _ClearFlags(STATE_FORCE_PRESSED); -} - -// IsPressed -bool -IconButton::IsPressed() const -{ - return _HasFlags(STATE_FORCE_PRESSED); -} - -status_t -IconButton::SetIcon(int32 resourceID) -{ - app_info info; - status_t status = be_app->GetAppInfo(&info); - if (status != B_OK) - return status; - - BResources resources(&info.ref); - status = resources.InitCheck(); - if (status != B_OK) - return status; - - size_t size; - const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE, resourceID, - &size); - if (data != NULL) { - BBitmap bitmap(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_RGBA32); - status = bitmap.InitCheck(); - if (status != B_OK) - return status; - status = BIconUtils::GetVectorIcon(reinterpret_cast(data), - size, &bitmap); - if (status != B_OK) - return status; - return SetIcon(&bitmap); - } -// const void* data = resources.LoadResource(B_BITMAP_TYPE, resourceID, &size); - return B_ERROR; -} - -// SetIcon -status_t -IconButton::SetIcon(const char* pathToBitmap) -{ - if (pathToBitmap == NULL) - return B_BAD_VALUE; - - status_t status = B_BAD_VALUE; - BBitmap* fileBitmap = NULL; - // try to load bitmap from either relative or absolute path - BEntry entry(pathToBitmap, true); - if (!entry.Exists()) { - app_info info; - status = be_app->GetAppInfo(&info); - if (status == B_OK) { - BEntry app_entry(&info.ref, true); - BPath path; - app_entry.GetPath(&path); - status = path.InitCheck(); - if (status == B_OK) { - status = path.GetParent(&path); - if (status == B_OK) { - status = path.Append(pathToBitmap, true); - if (status == B_OK) - fileBitmap = BTranslationUtils::GetBitmap(path.Path()); - else - printf("IconButton::SetIcon() - path.Append() failed: %s\n", strerror(status)); - } else - printf("IconButton::SetIcon() - path.GetParent() failed: %s\n", strerror(status)); - } else - printf("IconButton::SetIcon() - path.InitCheck() failed: %s\n", strerror(status)); - } else - printf("IconButton::SetIcon() - be_app->GetAppInfo() failed: %s\n", strerror(status)); - } else - fileBitmap = BTranslationUtils::GetBitmap(pathToBitmap); - if (fileBitmap) { - status = _MakeBitmaps(fileBitmap); - delete fileBitmap; - } else - status = B_ERROR; - return status; -} - -// SetIcon -status_t -IconButton::SetIcon(const BBitmap* bitmap) -{ - if (bitmap && bitmap->ColorSpace() == B_CMAP8) { - status_t status = bitmap->InitCheck(); - if (status >= B_OK) { - if (BBitmap* rgb32Bitmap = _ConvertToRGB32(bitmap)) { - status = _MakeBitmaps(rgb32Bitmap); - delete rgb32Bitmap; - } else - status = B_NO_MEMORY; - } - return status; - } else - return _MakeBitmaps(bitmap); -} - -// SetIcon -status_t -IconButton::SetIcon(const BMimeType* fileType, bool small) -{ - status_t status = fileType ? fileType->InitCheck() : B_BAD_VALUE; - if (status >= B_OK) { - BBitmap* mimeBitmap = new(nothrow) BBitmap(BRect(0.0, 0.0, 15.0, 15.0), B_CMAP8); - if (mimeBitmap && mimeBitmap->IsValid()) { - status = fileType->GetIcon(mimeBitmap, small ? B_MINI_ICON : B_LARGE_ICON); - if (status >= B_OK) { - if (BBitmap* bitmap = _ConvertToRGB32(mimeBitmap)) { - status = _MakeBitmaps(bitmap); - delete bitmap; - } else - printf("IconButton::SetIcon() - B_RGB32 bitmap is not valid\n"); - } else - printf("IconButton::SetIcon() - fileType->GetIcon() failed: %s\n", strerror(status)); - } else - printf("IconButton::SetIcon() - B_CMAP8 bitmap is not valid\n"); - delete mimeBitmap; - } else - printf("IconButton::SetIcon() - fileType is not valid: %s\n", strerror(status)); - return status; -} - -// SetIcon -status_t -IconButton::SetIcon(const unsigned char* bitsFromQuickRes, - uint32 width, uint32 height, color_space format, bool convertToBW) -{ - status_t status = B_BAD_VALUE; - if (bitsFromQuickRes && width > 0 && height > 0) { - BBitmap* quickResBitmap = new(nothrow) BBitmap(BRect(0.0, 0.0, width - 1.0, height - 1.0), format); - status = quickResBitmap ? quickResBitmap->InitCheck() : B_ERROR; - if (status >= B_OK) { - // It doesn't look right to copy BitsLength() bytes, but bitmaps - // exported from QuickRes still contain their padding, so it is alright. - memcpy(quickResBitmap->Bits(), bitsFromQuickRes, quickResBitmap->BitsLength()); - if (format != B_RGB32 && format != B_RGBA32 && format != B_RGB32_BIG && format != B_RGBA32_BIG) { - // colorspace needs conversion - BBitmap* bitmap = new(nothrow) BBitmap(quickResBitmap->Bounds(), B_RGB32, true); - if (bitmap && bitmap->IsValid()) { - BView* helper = new BView(bitmap->Bounds(), "helper", - B_FOLLOW_NONE, B_WILL_DRAW); - if (bitmap->Lock()) { - bitmap->AddChild(helper); - helper->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - helper->FillRect(helper->Bounds()); - helper->SetDrawingMode(B_OP_OVER); - helper->DrawBitmap(quickResBitmap, BPoint(0.0, 0.0)); - helper->Sync(); - bitmap->Unlock(); - } - status = _MakeBitmaps(bitmap); - } else - printf("IconButton::SetIcon() - B_RGB32 bitmap is not valid\n"); - delete bitmap; - } else { - // native colorspace (32 bits) - if (convertToBW) { - // convert to gray scale icon - uint8* bits = (uint8*)quickResBitmap->Bits(); - uint32 bpr = quickResBitmap->BytesPerRow(); - for (uint32 y = 0; y < height; y++) { - uint8* handle = bits; - uint8 gray; - for (uint32 x = 0; x < width; x++) { - gray = uint8((116 * handle[0] + 600 * handle[1] + 308 * handle[2]) / 1024); - handle[0] = gray; - handle[1] = gray; - handle[2] = gray; - handle += 4; - } - bits += bpr; - } - } - status = _MakeBitmaps(quickResBitmap); - } - } else - printf("IconButton::SetIcon() - error allocating bitmap: %s\n", strerror(status)); - delete quickResBitmap; - } - return status; -} - -// ClearIcon -void -IconButton::ClearIcon() -{ - _DeleteBitmaps(); - _Update(); -} - -void -IconButton::TrimIcon(bool keepAspect) -{ - if (fNormalBitmap == NULL) - return; - - uint8* bits = (uint8*)fNormalBitmap->Bits(); - uint32 bpr = fNormalBitmap->BytesPerRow(); - uint32 width = fNormalBitmap->Bounds().IntegerWidth() + 1; - uint32 height = fNormalBitmap->Bounds().IntegerHeight() + 1; - BRect trimmed(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN); - for (uint32 y = 0; y < height; y++) { - uint8* b = bits + 3; - bool rowHasAlpha = false; - for (uint32 x = 0; x < width; x++) { - if (*b) { - rowHasAlpha = true; - if (x < trimmed.left) - trimmed.left = x; - if (x > trimmed.right) - trimmed.right = x; - } - b += 4; - } - if (rowHasAlpha) { - if (y < trimmed.top) - trimmed.top = y; - if (y > trimmed.bottom) - trimmed.bottom = y; - } - bits += bpr; - } - if (!trimmed.IsValid()) - return; - if (keepAspect) { - float minInset = trimmed.left; - minInset = min_c(minInset, trimmed.top); - minInset = min_c(minInset, fNormalBitmap->Bounds().right - trimmed.right); - minInset = min_c(minInset, fNormalBitmap->Bounds().bottom - trimmed.bottom); - trimmed = fNormalBitmap->Bounds().InsetByCopy(minInset, minInset); - } - trimmed = trimmed & fNormalBitmap->Bounds(); - BBitmap trimmedBitmap(trimmed.OffsetToCopy(B_ORIGIN), - B_BITMAP_NO_SERVER_LINK, B_RGBA32); - bits = (uint8*)fNormalBitmap->Bits(); - bits += 4 * (int32)trimmed.left + bpr * (int32)trimmed.top; - uint8* dst = (uint8*)trimmedBitmap.Bits(); - uint32 trimmedWidth = trimmedBitmap.Bounds().IntegerWidth() + 1; - uint32 trimmedHeight = trimmedBitmap.Bounds().IntegerHeight() + 1; - uint32 trimmedBPR = trimmedBitmap.BytesPerRow(); - for (uint32 y = 0; y < trimmedHeight; y++) { - memcpy(dst, bits, trimmedWidth * 4); - dst += trimmedBPR; - bits += bpr; - } - SetIcon(&trimmedBitmap); -} - -// Bitmap -BBitmap* -IconButton::Bitmap() const -{ - BBitmap* bitmap = NULL; - if (fNormalBitmap && fNormalBitmap->IsValid()) { - bitmap = new(nothrow) BBitmap(fNormalBitmap); - if (bitmap->IsValid()) { - // TODO: remove this functionality when we use real transparent bitmaps - uint8* bits = (uint8*)bitmap->Bits(); - uint32 bpr = bitmap->BytesPerRow(); - uint32 width = bitmap->Bounds().IntegerWidth() + 1; - uint32 height = bitmap->Bounds().IntegerHeight() + 1; - color_space format = bitmap->ColorSpace(); - if (format == B_CMAP8) { - // replace gray with magic transparent index - } else if (format == B_RGB32) { - for (uint32 y = 0; y < height; y++) { - uint8* bitsHandle = bits; - for (uint32 x = 0; x < width; x++) { - if (bitsHandle[0] == 216 - && bitsHandle[1] == 216 - && bitsHandle[2] == 216) { - bitsHandle[3] = 0; // make this pixel completely transparent - } - bitsHandle += 4; - } - bits += bpr; - } - } - } else { - delete bitmap; - bitmap = NULL; - } - } - return bitmap; -} - -// DrawBorder -bool -IconButton::DrawBorder() const -{ - return ((IsEnabled() && (_HasFlags(STATE_INSIDE) - || _HasFlags(STATE_TRACKING))) || _HasFlags(STATE_FORCE_PRESSED)); -} - -// DrawNormalBorder -void -IconButton::DrawNormalBorder(BRect r, rgb_color background, - rgb_color shadow, rgb_color darkShadow, - rgb_color lightShadow, rgb_color light) -{ - _DrawFrame(r, shadow, darkShadow, light, lightShadow); -} - -// DrawPressedBorder -void -IconButton::DrawPressedBorder(BRect r, rgb_color background, - rgb_color shadow, rgb_color darkShadow, - rgb_color lightShadow, rgb_color light) -{ - _DrawFrame(r, shadow, light, darkShadow, background); -} - -// IsValid -bool -IconButton::IsValid() const -{ - return (fNormalBitmap && fDisabledBitmap && fClickedBitmap - && fDisabledClickedBitmap - && fNormalBitmap->IsValid() - && fDisabledBitmap->IsValid() - && fClickedBitmap->IsValid() - && fDisabledClickedBitmap->IsValid()); -} - -// Value -int32 -IconButton::Value() const -{ - return _HasFlags(STATE_PRESSED) ? B_CONTROL_ON : B_CONTROL_OFF; -} - -// SetValue -void -IconButton::SetValue(int32 value) -{ - if (value) - _AddFlags(STATE_PRESSED); - else - _ClearFlags(STATE_PRESSED); -} - -// IsEnabled -bool -IconButton::IsEnabled() const -{ - return _HasFlags(STATE_ENABLED) ? B_CONTROL_ON : B_CONTROL_OFF; -} - -// SetEnabled -void -IconButton::SetEnabled(bool enabled) -{ - if (enabled) - _AddFlags(STATE_ENABLED); - else - _ClearFlags(STATE_ENABLED | STATE_TRACKING | STATE_INSIDE); -} - -// _ConvertToRGB32 -BBitmap* -IconButton::_ConvertToRGB32(const BBitmap* bitmap) const -{ - BBitmap* convertedBitmap = new(nothrow) BBitmap(bitmap->Bounds(), - B_BITMAP_ACCEPTS_VIEWS, B_RGBA32); - if (convertedBitmap && convertedBitmap->IsValid()) { - memset(convertedBitmap->Bits(), 0, convertedBitmap->BitsLength()); - BView* helper = new BView(bitmap->Bounds(), "helper", - B_FOLLOW_NONE, B_WILL_DRAW); - if (convertedBitmap->Lock()) { - convertedBitmap->AddChild(helper); - helper->SetDrawingMode(B_OP_OVER); - helper->DrawBitmap(bitmap, BPoint(0.0, 0.0)); - helper->Sync(); - convertedBitmap->Unlock(); - } - } else { - delete convertedBitmap; - convertedBitmap = NULL; - } - return convertedBitmap; -} - -// _MakeBitmaps -status_t -IconButton::_MakeBitmaps(const BBitmap* bitmap) -{ - status_t status = bitmap ? bitmap->InitCheck() : B_BAD_VALUE; - if (status >= B_OK) { - // make our own versions of the bitmap - BRect b(bitmap->Bounds()); - _DeleteBitmaps(); - color_space format = bitmap->ColorSpace(); - fNormalBitmap = new(nothrow) BBitmap(b, format); - fDisabledBitmap = new(nothrow) BBitmap(b, format); - fClickedBitmap = new(nothrow) BBitmap(b, format); - fDisabledClickedBitmap = new(nothrow) BBitmap(b, format); - if (IsValid()) { - // copy bitmaps from file bitmap - uint8* nBits = (uint8*)fNormalBitmap->Bits(); - uint8* dBits = (uint8*)fDisabledBitmap->Bits(); - uint8* cBits = (uint8*)fClickedBitmap->Bits(); - uint8* dcBits = (uint8*)fDisabledClickedBitmap->Bits(); - uint8* fBits = (uint8*)bitmap->Bits(); - int32 nbpr = fNormalBitmap->BytesPerRow(); - int32 fbpr = bitmap->BytesPerRow(); - int32 pixels = b.IntegerWidth() + 1; - int32 lines = b.IntegerHeight() + 1; - // nontransparent version: - if (format == B_RGB32 || format == B_RGB32_BIG) { - // iterate over color components - for (int32 y = 0; y < lines; y++) { - for (int32 x = 0; x < pixels; x++) { - int32 nOffset = 4 * x; - int32 fOffset = 4 * x; - nBits[nOffset + 0] = fBits[fOffset + 0]; - nBits[nOffset + 1] = fBits[fOffset + 1]; - nBits[nOffset + 2] = fBits[fOffset + 2]; - nBits[nOffset + 3] = 255; - // clicked bits are darker (lame method...) - cBits[nOffset + 0] = (uint8)((float)nBits[nOffset + 0] * 0.8); - cBits[nOffset + 1] = (uint8)((float)nBits[nOffset + 1] * 0.8); - cBits[nOffset + 2] = (uint8)((float)nBits[nOffset + 2] * 0.8); - cBits[nOffset + 3] = 255; - // disabled bits have less contrast (lame method...) - uint8 grey = 216; - float dist = (nBits[nOffset + 0] - grey) * 0.4; - dBits[nOffset + 0] = (uint8)(grey + dist); - dist = (nBits[nOffset + 1] - grey) * 0.4; - dBits[nOffset + 1] = (uint8)(grey + dist); - dist = (nBits[nOffset + 2] - grey) * 0.4; - dBits[nOffset + 2] = (uint8)(grey + dist); - dBits[nOffset + 3] = 255; - // disabled bits have less contrast (lame method...) - grey = 188; - dist = (nBits[nOffset + 0] - grey) * 0.4; - dcBits[nOffset + 0] = (uint8)(grey + dist); - dist = (nBits[nOffset + 1] - grey) * 0.4; - dcBits[nOffset + 1] = (uint8)(grey + dist); - dist = (nBits[nOffset + 2] - grey) * 0.4; - dcBits[nOffset + 2] = (uint8)(grey + dist); - dcBits[nOffset + 3] = 255; - } - nBits += nbpr; - dBits += nbpr; - cBits += nbpr; - dcBits += nbpr; - fBits += fbpr; - } - // transparent version: - } else if (format == B_RGBA32 || format == B_RGBA32_BIG) { - // iterate over color components - for (int32 y = 0; y < lines; y++) { - for (int32 x = 0; x < pixels; x++) { - int32 nOffset = 4 * x; - int32 fOffset = 4 * x; - nBits[nOffset + 0] = fBits[fOffset + 0]; - nBits[nOffset + 1] = fBits[fOffset + 1]; - nBits[nOffset + 2] = fBits[fOffset + 2]; - nBits[nOffset + 3] = fBits[fOffset + 3]; - // clicked bits are darker (lame method...) - cBits[nOffset + 0] = (uint8)(nBits[nOffset + 0] * 0.8); - cBits[nOffset + 1] = (uint8)(nBits[nOffset + 1] * 0.8); - cBits[nOffset + 2] = (uint8)(nBits[nOffset + 2] * 0.8); - cBits[nOffset + 3] = fBits[fOffset + 3]; - // disabled bits have less opacity - - uint8 grey = ((uint16)nBits[nOffset + 0] * 10 - + nBits[nOffset + 1] * 60 - + nBits[nOffset + 2] * 30) / 100; - float dist = (nBits[nOffset + 0] - grey) * 0.3; - dBits[nOffset + 0] = (uint8)(grey + dist); - dist = (nBits[nOffset + 1] - grey) * 0.3; - dBits[nOffset + 1] = (uint8)(grey + dist); - dist = (nBits[nOffset + 2] - grey) * 0.3; - dBits[nOffset + 2] = (uint8)(grey + dist); - dBits[nOffset + 3] = (uint8)(fBits[fOffset + 3] * 0.3); - // disabled bits have less contrast (lame method...) - dcBits[nOffset + 0] = (uint8)(dBits[nOffset + 0] * 0.8); - dcBits[nOffset + 1] = (uint8)(dBits[nOffset + 1] * 0.8); - dcBits[nOffset + 2] = (uint8)(dBits[nOffset + 2] * 0.8); - dcBits[nOffset + 3] = (uint8)(fBits[fOffset + 3] * 0.3); - } - nBits += nbpr; - dBits += nbpr; - cBits += nbpr; - dcBits += nbpr; - fBits += fbpr; - } - // unsupported format - } else { - printf("IconButton::_MakeBitmaps() - bitmap has unsupported colorspace\n"); - status = B_MISMATCHED_VALUES; - _DeleteBitmaps(); - } - } else { - printf("IconButton::_MakeBitmaps() - error allocating local bitmaps\n"); - status = B_NO_MEMORY; - _DeleteBitmaps(); - } - } else - printf("IconButton::_MakeBitmaps() - bitmap is not valid\n"); - return status; -} - -// _DeleteBitmaps -void -IconButton::_DeleteBitmaps() -{ - delete fNormalBitmap; - fNormalBitmap = NULL; - delete fDisabledBitmap; - fDisabledBitmap = NULL; - delete fClickedBitmap; - fClickedBitmap = NULL; - delete fDisabledClickedBitmap; - fDisabledClickedBitmap = NULL; -} - -// _Update -void -IconButton::_Update() -{ - if (LockLooper()) { - Invalidate(); - UnlockLooper(); - } -} - -// _AddFlags -void -IconButton::_AddFlags(uint32 flags) -{ - if (!(fButtonState & flags)) { - fButtonState |= flags; - _Update(); - } -} - -// _ClearFlags -void -IconButton::_ClearFlags(uint32 flags) -{ - if (fButtonState & flags) { - fButtonState &= ~flags; - _Update(); - } -} - -// _HasFlags -bool -IconButton::_HasFlags(uint32 flags) const -{ - return (fButtonState & flags); -} - -// _DrawFrame -void -IconButton::_DrawFrame(BRect r, rgb_color col1, rgb_color col2, - rgb_color col3, rgb_color col4) -{ - BeginLineArray(8); - AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col1); - AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col1); - AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col2); - AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col2); - r.InsetBy(1.0, 1.0); - AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col3); - AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col3); - AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col4); - AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col4); - EndLineArray(); -} diff --git a/src/apps/webpositive/support/IconButton.h b/src/apps/webpositive/support/IconButton.h deleted file mode 100644 index 2876dd8cfd..0000000000 --- a/src/apps/webpositive/support/IconButton.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2006-2010, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Stephan Aßmus - */ - -/** gui class that loads an image from disk and shows it - as clickable button */ - -// TODO: inherit from BControl? - -// NOTE: this file is a duplicate of the version in Icon-O-Matic/generic -// it should be placed into a common folder for generic useful stuff - -#ifndef ICON_BUTTON_H -#define ICON_BUTTON_H - -#include -#include -#include - -class BBitmap; -class BMimeType; - -class IconButton : public BView, public BInvoker { -public: - IconButton(const char* name, - uint32 id, - const char* label = NULL, - BMessage* message = NULL, - BHandler* target = NULL); - virtual ~IconButton(); - - // BView interface - virtual void MessageReceived(BMessage* message); - virtual void AttachedToWindow(); - virtual void Draw(BRect updateRect); - virtual void MouseDown(BPoint where); - virtual void MouseUp(BPoint where); - virtual void MouseMoved(BPoint where, uint32 transit, - const BMessage* message); - virtual void GetPreferredSize(float* width, - float* height); - virtual BSize MinSize(); - virtual BSize MaxSize(); - - - // BInvoker interface - virtual status_t Invoke(BMessage* message = NULL); - - // IconButton - bool IsValid() const; - - virtual int32 Value() const; - virtual void SetValue(int32 value); - - bool IsEnabled() const; - void SetEnabled(bool enable); - - void SetPressed(bool pressed); - bool IsPressed() const; - uint32 ID() const - { return fID; } - - status_t SetIcon(int32 resourceID); - status_t SetIcon(const char* pathToBitmap); - status_t SetIcon(const BBitmap* bitmap); - status_t SetIcon(const BMimeType* fileType, - bool small = true); - status_t SetIcon(const unsigned char* bitsFromQuickRes, - uint32 width, uint32 height, - color_space format, - bool convertToBW = false); - void ClearIcon(); - void TrimIcon(bool keepAspect = true); - - BBitmap* Bitmap() const; - // caller has to delete the returned bitmap - - virtual bool DrawBorder() const; - virtual void DrawNormalBorder(BRect r, - rgb_color background, - rgb_color shadow, - rgb_color darkShadow, - rgb_color lightShadow, - rgb_color light); - virtual void DrawPressedBorder(BRect r, - rgb_color background, - rgb_color shadow, - rgb_color darkShadow, - rgb_color lightShadow, - rgb_color light); - -protected: - enum { - STATE_NONE = 0x0000, - STATE_TRACKING = 0x0001, - STATE_PRESSED = 0x0002, - STATE_ENABLED = 0x0004, - STATE_INSIDE = 0x0008, - STATE_FORCE_PRESSED = 0x0010, - }; - - void _AddFlags(uint32 flags); - void _ClearFlags(uint32 flags); - bool _HasFlags(uint32 flags) const; - - void _DrawFrame(BRect frame, - rgb_color col1, - rgb_color col2, - rgb_color col3, - rgb_color col4); - -// private: - BBitmap* _ConvertToRGB32(const BBitmap* bitmap) const; - status_t _MakeBitmaps(const BBitmap* bitmap); - void _DeleteBitmaps(); - void _SendMessage() const; - void _Update(); - - uint32 fButtonState; - int32 fID; - BBitmap* fNormalBitmap; - BBitmap* fDisabledBitmap; - BBitmap* fClickedBitmap; - BBitmap* fDisabledClickedBitmap; - BString fLabel; - - BHandler* fTargetCache; -}; - -#endif // ICON_BUTTON_H diff --git a/src/apps/webpositive/support/IconUtils.h b/src/apps/webpositive/support/IconUtils.h deleted file mode 100644 index fdcfbd946f..0000000000 --- a/src/apps/webpositive/support/IconUtils.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2006-2008, Haiku. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _ICON_UTILS_H -#define _ICON_UTILS_H - - -#include - -class BBitmap; -class BNode; - - -// This class is a little different from many other classes. -// You don't create an instance of it; you just call its various -// static member functions for utility-like operations. -class BIconUtils { - BIconUtils(); - ~BIconUtils(); - BIconUtils(const BIconUtils&); - BIconUtils& operator=(const BIconUtils&); - -public: - - // Utility function to import an icon from the node that - // has either of the provided attribute names. Which icon type - // is preferred (vector, small or large B_CMAP8 icon) depends - // on the colorspace of the provided bitmap. If the colorspace - // is B_CMAP8, B_CMAP8 icons are preferred. In that case, the - // bitmap size must also match the provided icon_size "size"! - static status_t GetIcon(BNode* node, - const char* vectorIconAttrName, - const char* smallIconAttrName, - const char* largeIconAttrName, - icon_size size, BBitmap* result); - - // Utility functions to import a vector icon in "flat icon" - // format from a BNode attribute or from a flat buffer in - // memory into the preallocated BBitmap "result". - // The colorspace of result needs to be B_RGBA32 or at - // least B_RGB32 (though that makes less sense). The icon - // will be scaled from it's "native" size of 64x64 to the - // size of the bitmap, the scale is derived from the bitmap - // width, the bitmap should have square dimension, or the - // icon will be cut off at the bottom (or have room left). - static status_t GetVectorIcon(BNode* node, - const char* attrName, BBitmap* result); - - static status_t GetVectorIcon(const uint8* buffer, - size_t size, BBitmap* result); - - // Utility function to import an "old" BeOS icon in B_CMAP8 - // colorspace from either the small icon attribute or the - // large icon attribute as given in "smallIconAttrName" and - // "largeIconAttrName". Which icon is loaded depends on - // the given "size". - static status_t GetCMAP8Icon(BNode* node, - const char* smallIconAttrName, - const char* largeIconAttrName, - icon_size size, BBitmap* icon); - - // Utility functions to convert from old icon colorspace - // into colorspace of BBitmap "result" (should be B_RGBA32 - // to make any sense). - static status_t ConvertFromCMAP8(BBitmap* source, - BBitmap* result); - static status_t ConvertToCMAP8(BBitmap* source, - BBitmap* result); - - static status_t ConvertFromCMAP8(const uint8* data, - uint32 width, uint32 height, - uint32 bytesPerRow, BBitmap* result); - - static status_t ConvertToCMAP8(const uint8* data, - uint32 width, uint32 height, - uint32 bytesPerRow, BBitmap* result); -}; - -#endif // _ICON_UTILS_H diff --git a/src/apps/webpositive/support/NavMenu.h b/src/apps/webpositive/support/NavMenu.h deleted file mode 100644 index 127d94f255..0000000000 --- a/src/apps/webpositive/support/NavMenu.h +++ /dev/null @@ -1,168 +0,0 @@ -/* -Open Tracker License - -Terms and Conditions - -Copyright (c) 1991-2000, Be Incorporated. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice applies to all licensees -and shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BE INCORPORATED 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 Be Incorporated shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization from Be Incorporated. - -Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks -of Be Incorporated in the United States and other countries. Other brand product -names are registered trademarks or trademarks of their respective holders. -All rights reserved. -*/ - -// NavMenu is a hierarchical menu of volumes, folders, files and queries -// displays icons, uses the SlowMenu API for full interruptability - -#ifndef NAV_MENU_H -#define NAV_MENU_H - - -#include -#include -#include - -#include "SlowMenu.h" - - -template class BObjectList; -class BMenuItem; - -namespace BPrivate { - -class Model; -class BContainerWindow; -class ModelMenuItem; -class EntryListBase; - - -class TrackingHookData { - public: - TrackingHookData() - : - fTrackingHook(NULL), - fDragMessage(NULL) - { - } - - bool (*fTrackingHook)(BMenu *, void *); - BMessenger fTarget; - const BMessage *fDragMessage; -}; - - -class BNavMenu : public BSlowMenu { - public: - BNavMenu(const char* title, uint32 message, const BHandler *, - BWindow *parentWindow = NULL, const BObjectList *list = NULL); - BNavMenu(const char* title, uint32 message, const BMessenger &, - BWindow *parentWindow = NULL, const BObjectList *list = NULL); - // parentWindow, if specified, will be closed if nav menu item invoked - // with option held down - - virtual ~BNavMenu(); - - virtual void AttachedToWindow(); - virtual void DetachedFromWindow(); - - void SetNavDir(const entry_ref *); - void ForceRebuild(); - bool NeedsToRebuild() const; - // will cause menu to get rebuilt next time it is shown - - virtual void ResetTargets(); - void SetTarget(const BMessenger &); - BMessenger Target(); - - void SetTypesList(const BObjectList *list); - const BObjectList *TypesList() const; - - void AddNavDir(const Model *model, uint32 what, BHandler *target, - bool populateSubmenu); - - void AddNavParentDir(const char *name, const Model *model, uint32 what, BHandler *target); - void AddNavParentDir(const Model *model, uint32 what, BHandler *target); - void SetShowParent(bool show); - - static int32 GetMaxMenuWidth(); - - static int CompareFolderNamesFirstOne(const BMenuItem *, const BMenuItem *); - static int CompareOne(const BMenuItem *, const BMenuItem *); - - static ModelMenuItem *NewModelItem(Model *, const BMessage *, const BMessenger &, - bool suppressFolderHierarchy=false, BContainerWindow * = NULL, - const BObjectList *typeslist = NULL, - TrackingHookData *hook = NULL); - - TrackingHookData *InitTrackingHook(bool (*hookfunction)(BMenu *, void *), - const BMessenger *target, const BMessage *dragMessage); - - protected: - virtual bool StartBuildingItemList(); - virtual bool AddNextItem(); - virtual void DoneBuildingItemList(); - virtual void ClearMenuBuildingState(); - - void BuildVolumeMenu(); - - void AddOneItem(Model *); - void AddRootItemsIfNeeded(); - void AddTrashItem(); - static void SetTrackingHookDeep(BMenu *, bool (*)(BMenu *, void *), void *); - - entry_ref fNavDir; - BMessage fMessage; - BMessenger fMessenger; - BWindow *fParentWindow; - - // menu building state - uint8 fFlags; - BObjectList *fItemList; - EntryListBase *fContainer; - bool fIteratingDesktop; - - const BObjectList *fTypesList; - - TrackingHookData fTrackingHook; -}; - -// Spring Loaded Folder convenience routines -// used in both Tracker and Deskbar -#ifndef _IMPEXP_TRACKER -# define _IMPEXP_TRACKER -#endif -_IMPEXP_TRACKER bool SpringLoadedFolderCompareMessages(const BMessage *incoming, - const BMessage *dragmessage); -_IMPEXP_TRACKER void SpringLoadedFolderSetMenuStates(const BMenu *menu, - const BObjectList *typeslist); -_IMPEXP_TRACKER void SpringLoadedFolderAddUniqueTypeToList(entry_ref *ref, - BObjectList *typeslist); -_IMPEXP_TRACKER void SpringLoadedFolderCacheDragData(const BMessage *incoming, - BMessage **, BObjectList **typeslist); - -} // namespace BPrivate - -using namespace BPrivate; - -#endif // NAV_MENU_H diff --git a/src/apps/webpositive/support/OpenHashTable.h b/src/apps/webpositive/support/OpenHashTable.h deleted file mode 100644 index 437fbed170..0000000000 --- a/src/apps/webpositive/support/OpenHashTable.h +++ /dev/null @@ -1,514 +0,0 @@ -/* -Open Tracker License - -Terms and Conditions - -Copyright (c) 1991-2000, Be Incorporated. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice applies to all licensees -and shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BE INCORPORATED 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 Be Incorporated shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization from Be Incorporated. - -Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks -of Be Incorporated in the United States and other countries. Other brand product -names are registered trademarks or trademarks of their respective holders. -All rights reserved. -*/ - -// bonefish: -// * removed need for exceptions -// * fixed warnings -// * implemented rehashing -// * added RemoveAll() -// TODO: -// * shrinking of element vectors - -// Hash table with open addresssing - -#ifndef __OPEN_HASH_TABLE__ -#define __OPEN_HASH_TABLE__ - -#include -#include - -// don't include -#ifndef ASSERT -# define ASSERT(E) (void)0 -#endif -#ifndef TRESPASS -# define TRESPASS() (void)0 -#endif - -namespace BPrivate { - -template -class ElementVector { - // element vector for OpenHashTable needs to implement this - // interface -public: - Element &At(int32 index); - Element *Add(); - int32 IndexOf(const Element &) const; - void Remove(int32 index); -}; - -class OpenHashElement { -public: - uint32 Hash() const; - bool operator==(const OpenHashElement &) const; - void Adopt(OpenHashElement &); - // low overhead copy, original element is in undefined state - // after call (calls Adopt on BString members, etc.) - int32 fNext; -}; - -const uint32 kPrimes [] = { - 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, - 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859, - 134217689, 268435399, 536870909, 1073741789, 2147483647, 0 -}; - -template > -class OpenHashTable { -public: - OpenHashTable(int32 minSize, ElementVec *elementVector = 0, - float maxLoadFactor = 0.8); - // it is up to the subclass of OpenHashTable to supply - // elementVector - ~OpenHashTable(); - - bool InitCheck() const; - - void SetElementVector(ElementVec *elementVector); - - Element *FindFirst(uint32 elementHash) const; - Element *Add(uint32 elementHash); - - void Remove(Element *element, bool dontRehash = false); - void RemoveAll(); - - // when calling Add, any outstanding element pointer may become - // invalid; to deal with this, get the element index and restore - // it after the add - int32 ElementIndex(const Element *) const; - Element *ElementAt(int32 index) const; - - int32 ArraySize() const; - int32 VectorSize() const; - int32 CountElements() const; - -protected: - static int32 OptimalSize(int32 minSize); - -private: - bool _RehashIfNeeded(); - bool _Rehash(); - - int32 fArraySize; - int32 fInitialSize; - int32 fElementCount; - int32 *fHashArray; - ElementVec *fElementVector; - float fMaxLoadFactor; -}; - -template -class OpenHashElementArray : public ElementVector { - // this is a straightforward implementation of an element vector - // deleting is handled by linking deleted elements into a free list - // the vector never shrinks -public: - OpenHashElementArray(int32 initialSize); - ~OpenHashElementArray(); - - bool InitCheck() const; - - Element &At(int32 index); - const Element &At(int32 index) const; - Element *Add(const Element &); - Element *Add(); - void Remove(int32 index); - int32 IndexOf(const Element &) const; - int32 Size() const; - -private: - Element *fData; - int32 fSize; - int32 fNextFree; - int32 fNextDeleted; -}; - - -//----------------------------------- - -template -OpenHashTable::OpenHashTable(int32 minSize, - ElementVec *elementVector, float maxLoadFactor) - : fArraySize(OptimalSize(minSize)), - fInitialSize(fArraySize), - fElementCount(0), - fElementVector(elementVector), - fMaxLoadFactor(maxLoadFactor) -{ - // sanity check the maximal load factor - if (fMaxLoadFactor < 0.5) - fMaxLoadFactor = 0.5; - // allocate and init the array - fHashArray = (int32*)calloc(fArraySize, sizeof(int32)); - if (fHashArray) { - for (int32 index = 0; index < fArraySize; index++) - fHashArray[index] = -1; - } -} - -template -OpenHashTable::~OpenHashTable() -{ - RemoveAll(); - free(fHashArray); -} - -template -bool -OpenHashTable::InitCheck() const -{ - return (fHashArray && fElementVector); -} - -template -int32 -OpenHashTable::OptimalSize(int32 minSize) -{ - for (int32 index = 0; ; index++) - if (!kPrimes[index] || kPrimes[index] >= (uint32)minSize) - return (int32)kPrimes[index]; - - return 0; -} - -template -Element * -OpenHashTable::FindFirst(uint32 hash) const -{ - ASSERT(fElementVector); - hash %= fArraySize; - if (fHashArray[hash] < 0) - return 0; - - return &fElementVector->At(fHashArray[hash]); -} - -template -int32 -OpenHashTable::ElementIndex(const Element *element) const -{ - return fElementVector->IndexOf(*element); -} - -template -Element * -OpenHashTable::ElementAt(int32 index) const -{ - return &fElementVector->At(index); -} - -template -int32 -OpenHashTable::ArraySize() const -{ - return fArraySize; -} - -template -int32 -OpenHashTable::VectorSize() const -{ - return fElementVector->Size(); -} - -template -int32 -OpenHashTable::CountElements() const -{ - return fElementCount; -} - - -template -Element * -OpenHashTable::Add(uint32 hash) -{ - ASSERT(fElementVector); - _RehashIfNeeded(); - hash %= fArraySize; - Element *result = fElementVector->Add(); - if (result) { - result->fNext = fHashArray[hash]; - fHashArray[hash] = fElementVector->IndexOf(*result); - fElementCount++; - } - return result; -} - -template -void -OpenHashTable::Remove(Element *element, bool dontRehash) -{ - if (!dontRehash) - _RehashIfNeeded(); - uint32 hash = element->Hash() % fArraySize; - int32 next = fHashArray[hash]; - ASSERT(next >= 0); - - if (&fElementVector->At(next) == element) { - fHashArray[hash] = element->fNext; - fElementVector->Remove(next); - fElementCount--; - return; - } - - for (int32 index = next; index >= 0; ) { - // look for an existing match in table - next = fElementVector->At(index).fNext; - if (next < 0) { - TRESPASS(); - return; - } - - if (&fElementVector->At(next) == element) { - fElementVector->At(index).fNext = element->fNext; - fElementVector->Remove(next); - fElementCount--; - return; - } - index = next; - } -} - -template -void -OpenHashTable::RemoveAll() -{ - for (int32 i = 0; fElementCount > 0 && i < fArraySize; i++) { - int32 index = fHashArray[i]; - while (index >= 0) { - Element* element = &fElementVector->At(index); - int32 next = element->fNext; - fElementVector->Remove(index); - fElementCount--; - index = next; - } - fHashArray[i] = -1; - } - _RehashIfNeeded(); -} - -template -void -OpenHashTable::SetElementVector(ElementVec *elementVector) -{ - fElementVector = elementVector; -} - -// _RehashIfNeeded -template -bool -OpenHashTable::_RehashIfNeeded() -{ - // The load factor range [fMaxLoadFactor / 3, fMaxLoadFactor] is fine, - // I think. After rehashing the load factor will be about - // fMaxLoadFactor * 2 / 3, respectively fMaxLoadFactor / 2. - float loadFactor = (float)fElementCount / (float)fArraySize; - if (loadFactor > fMaxLoadFactor - || (fArraySize > fInitialSize && loadFactor < fMaxLoadFactor / 3)) { - return _Rehash(); - } - return true; -} - -// _Rehash -template -bool -OpenHashTable::_Rehash() -{ - bool result = true; - int32 newSize = int32(fElementCount * 1.73 * fMaxLoadFactor); - newSize = (fInitialSize > newSize ? fInitialSize : newSize); - if (newSize != fArraySize) { - // allocate a new array - int32 *newHashArray = (int32*)calloc(newSize, sizeof(int32)); - if (newHashArray) { - // init the new hash array - for (int32 index = 0; index < newSize; index++) - newHashArray[index] = -1; - // iterate through all elements and put them into the new - // hash array - for (int i = 0; i < fArraySize; i++) { - int32 index = fHashArray[i]; - while (index >= 0) { - // insert the element in the new array - Element &element = fElementVector->At(index); - int32 next = element.fNext; - uint32 hash = (element.Hash() % newSize); - element.fNext = newHashArray[hash]; - newHashArray[hash] = index; - // next element in old list - index = next; - } - } - // delete the old array and set the new one - free(fHashArray); - fHashArray = newHashArray; - fArraySize = newSize; - } else - result = false; - } - return result; -} - - -template -OpenHashElementArray::OpenHashElementArray(int32 initialSize) - : fSize(initialSize), - fNextFree(0), - fNextDeleted(-1) -{ - fData = (Element*)calloc((size_t)initialSize, sizeof(Element)); -} - -template -OpenHashElementArray::~OpenHashElementArray() -{ - free(fData); -} - -template -bool -OpenHashElementArray::InitCheck() const -{ - return fData; -} - -template -Element & -OpenHashElementArray::At(int32 index) -{ - ASSERT(index < fSize); - return fData[index]; -} - -template -const Element & -OpenHashElementArray::At(int32 index) const -{ - ASSERT(index < fSize); - return fData[index]; -} - -template -int32 -OpenHashElementArray::IndexOf(const Element &element) const -{ - int32 result = &element - fData; - if (result < 0 || result > fSize) - return -1; - - return result; -} - -template -int32 -OpenHashElementArray::Size() const -{ - return fSize; -} - - -template -Element * -OpenHashElementArray::Add(const Element &newElement) -{ - Element *element = Add(); - if (element) - element.Adopt(newElement); - return element; -} - -#if DEBUG -const int32 kGrowChunk = 10; -#else -const int32 kGrowChunk = 1024; -#endif - -template -Element * -OpenHashElementArray::Add() -{ - int32 index = fNextFree; - if (fNextDeleted >= 0) { - index = fNextDeleted; - fNextDeleted = At(index).fNext; - } else if (fNextFree >= fSize - 1) { - int32 newSize = fSize + kGrowChunk; -/* - Element *newData = (Element *)calloc((size_t)newSize , sizeof(Element)); - if (!newData) - return NULL; - memcpy(newData, fData, fSize * sizeof(Element)); - free(fData); -*/ - Element *newData = (Element*)realloc(fData, - (size_t)newSize * sizeof(Element)); - if (!newData) - return NULL; - - fData = newData; - fSize = newSize; - index = fNextFree; - fNextFree++; - } else - fNextFree++; - - new (&At(index)) Element; - // call placement new to initialize the element properly - ASSERT(At(index).fNext == -1); - - return &At(index); -} - -template -void -OpenHashElementArray::Remove(int32 index) -{ - // delete by chaining empty elements in a single linked - // list, reusing the next field - ASSERT(index < fSize); - At(index).~Element(); - // call the destructor explicitly to destroy the element - // properly - At(index).fNext = fNextDeleted; - fNextDeleted = index; -} - -} // namespace BPrivate - -using BPrivate::OpenHashTable; - -#endif // __OPEN_HASH_TABLE__ diff --git a/src/apps/webpositive/support/SlowMenu.h b/src/apps/webpositive/support/SlowMenu.h deleted file mode 100644 index 62e9156b07..0000000000 --- a/src/apps/webpositive/support/SlowMenu.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -Open Tracker License - -Terms and Conditions - -Copyright (c) 1991-2000, Be Incorporated. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice applies to all licensees -and shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BE INCORPORATED 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 Be Incorporated shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization from Be Incorporated. - -Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks -of Be Incorporated in the United States and other countries. Other brand product -names are registered trademarks or trademarks of their respective holders. -All rights reserved. -*/ - -#ifndef __SLOW_MENU__ -#define __SLOW_MENU__ - -#include -#include -#include - -// SlowMenu is a convenience class that makes it easier to -// use the AddDynamicItem callback to implement a menu that can -// checks periodically between creating new items and quits -// early if needed - -namespace BPrivate { - -class BSlowMenu : public BMenu { - public: - BSlowMenu(const char *title, menu_layout layout = B_ITEMS_IN_COLUMN); - - protected: - virtual bool StartBuildingItemList(); - // set up state to start building the item list - // returns false if setup failed - virtual bool AddNextItem() = 0; - // returns false if done - virtual void DoneBuildingItemList() = 0; - // default version adds items from itemList to menu and deletes - // the list; override to sort items first, etc. - - virtual void ClearMenuBuildingState() = 0; - - protected: - virtual bool AddDynamicItem(add_state state); - // this is the callback from BMenu, you shouldn't need to override this - - bool fMenuBuilt; -}; - -} // namespace BPrivate - -using namespace BPrivate; - -#endif /* __SLOW_MENU__ */ diff --git a/src/apps/webpositive/support/StringForSize.cpp b/src/apps/webpositive/support/StringForSize.cpp deleted file mode 100644 index ae7831e397..0000000000 --- a/src/apps/webpositive/support/StringForSize.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#include "StringForSize.h" - -#include - - -namespace BPrivate { - - -const char* -string_for_size(double size, char* string, size_t stringSize) -{ - double kib = size / 1024.0; - if (kib < 1.0) { - snprintf(string, stringSize, "%d bytes", (int)size); - return string; - } - double mib = kib / 1024.0; - if (mib < 1.0) { - snprintf(string, stringSize, "%3.2f KiB", kib); - return string; - } - double gib = mib / 1024.0; - if (gib < 1.0) { - snprintf(string, stringSize, "%3.2f MiB", mib); - return string; - } - double tib = gib / 1024.0; - if (tib < 1.0) { - snprintf(string, stringSize, "%3.2f GiB", gib); - return string; - } - snprintf(string, stringSize, "%.2f TiB", tib); - return string; -} - - -} // namespace BPrivate - diff --git a/src/apps/webpositive/support/StringForSize.h b/src/apps/webpositive/support/StringForSize.h deleted file mode 100644 index fa3e13b115..0000000000 --- a/src/apps/webpositive/support/StringForSize.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2010 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef STRING_FOR_SIZE_H -#define STRING_FOR_SIZE_H - -#include - - -namespace BPrivate { - - -const char* string_for_size(double size, char* string, size_t stringSize); - - -} // namespace BPrivate - - -using BPrivate::string_for_size; - - -#endif // COLOR_QUANTIZER_H diff --git a/src/apps/webpositive/svn_revision.cpp b/src/apps/webpositive/svn_revision.cpp deleted file mode 100644 index 9e415b5262..0000000000 --- a/src/apps/webpositive/svn_revision.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright 2006-2009, Ingo Weinhold - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include "svn_revision.h" - -const int32 kSVNRevision = 0; -// #include "svn_revision" -; diff --git a/src/apps/webpositive/svn_revision.h b/src/apps/webpositive/svn_revision.h deleted file mode 100644 index fff9e9b122..0000000000 --- a/src/apps/webpositive/svn_revision.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2006-2009, Ingo Weinhold - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#ifndef SVN_REVISION_H -#define SVN_REVISION_H - -#include - - -extern const int32 kSVNRevision; - - -#endif // SVN_REVISION_H diff --git a/src/apps/webpositive/tabview/TabContainerView.cpp b/src/apps/webpositive/tabview/TabContainerView.cpp index 8f9c899975..44910260e2 100644 --- a/src/apps/webpositive/tabview/TabContainerView.cpp +++ b/src/apps/webpositive/tabview/TabContainerView.cpp @@ -2,28 +2,7 @@ * Copyright (C) 2010 Rene Gollent * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "TabContainerView.h" @@ -35,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +24,10 @@ #include "TabView.h" +#undef B_TRANSLATION_CONTEXT +#define B_TRANSLATION_CONTEXT "Tab Manager" + + static const float kLeftTabInset = 4; @@ -468,8 +452,10 @@ TabContainerView::_MouseMoved(BPoint where, uint32 _transit, fLastMouseEventTab = tab; if (fLastMouseEventTab) fLastMouseEventTab->MouseMoved(where, B_ENTERED_VIEW, dragMessage); - else - fController->SetToolTip("Double-click or middle-click to open new tab."); + else { + fController->SetToolTip( + B_TRANSLATE("Double-click or middle-click to open new tab.")); + } } } diff --git a/src/apps/webpositive/tabview/TabContainerView.h b/src/apps/webpositive/tabview/TabContainerView.h index a5a7ee04fa..a740f4ad85 100644 --- a/src/apps/webpositive/tabview/TabContainerView.h +++ b/src/apps/webpositive/tabview/TabContainerView.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef TAB_CONTAINER_VIEW_H #define TAB_CONTAINER_VIEW_H diff --git a/src/apps/webpositive/tabview/TabManager.cpp b/src/apps/webpositive/tabview/TabManager.cpp index 29368f53fe..d5c587c111 100644 --- a/src/apps/webpositive/tabview/TabManager.cpp +++ b/src/apps/webpositive/tabview/TabManager.cpp @@ -2,28 +2,7 @@ * Copyright (C) 2010 Rene Gollent * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "TabManager.h" @@ -847,7 +826,7 @@ void TabManager::SelectTab(const BView* containedView) { int32 tabIndex = TabForView(containedView); - if (tabIndex > 0) + if (tabIndex >= 0) SelectTab(tabIndex); } diff --git a/src/apps/webpositive/tabview/TabManager.h b/src/apps/webpositive/tabview/TabManager.h index 97cd65c898..f2f676a7d7 100644 --- a/src/apps/webpositive/tabview/TabManager.h +++ b/src/apps/webpositive/tabview/TabManager.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef TAB_MANAGER_H diff --git a/src/apps/webpositive/tabview/TabView.cpp b/src/apps/webpositive/tabview/TabView.cpp index 7caeaaf71f..3ccb929e01 100644 --- a/src/apps/webpositive/tabview/TabView.cpp +++ b/src/apps/webpositive/tabview/TabView.cpp @@ -2,28 +2,7 @@ * Copyright (C) 2010 Rene Gollent * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #include "TabView.h" diff --git a/src/apps/webpositive/tabview/TabView.h b/src/apps/webpositive/tabview/TabView.h index 9f73c5a994..376bfa0d95 100644 --- a/src/apps/webpositive/tabview/TabView.h +++ b/src/apps/webpositive/tabview/TabView.h @@ -1,28 +1,7 @@ /* * Copyright (C) 2010 Stephan Aßmus * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef TAB_VIEW_H #define TAB_VIEW_H diff --git a/src/bin/Jamfile b/src/bin/Jamfile index d6f2c6137a..617ed5b2e2 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -10,7 +10,6 @@ UsePrivateHeaders app interface shared storage support tracker usb ; UsePrivateSystemHeaders ; SubDirHdrs $(HAIKU_TOP) src add-ons kernel file_cache ; UseLibraryHeaders ncurses ; -UseLibraryHeaders termcap ; local haiku-utils_rsrc = [ FGristFiles haiku-utils.rsrc ] ; @@ -69,11 +68,10 @@ StdBinCommands : : $(haiku-utils_rsrc) ; } -# standard commands that need libtermcap.a +# standard commands that need libncurses.a StdBinCommands top.c - tput.c - : libtermcap.a : $(haiku-utils_rsrc) ; + : libncurses.a : $(haiku-utils_rsrc) ; # standard commands that need libbe.so StdBinCommands diff --git a/src/bin/bash/Jamfile b/src/bin/bash/Jamfile index d5de2d3041..5adda6b3b6 100644 --- a/src/bin/bash/Jamfile +++ b/src/bin/bash/Jamfile @@ -88,7 +88,7 @@ BinCommand bash : $(jobControlSources) : libreadline.a libglob.a libbuiltins.a libtilde.a libsh.a - libtermcap.a $(TARGET_SELECT_UNAME_ETC_LIB) + libncurses.a $(TARGET_SELECT_UNAME_ETC_LIB) : bash.rdef ; # trap.c includes signames.h diff --git a/src/bin/bash/builtins/common.c b/src/bin/bash/builtins/common.c index 2c75b8419b..4e4361820e 100644 --- a/src/bin/bash/builtins/common.c +++ b/src/bin/bash/builtins/common.c @@ -64,7 +64,7 @@ #endif #if !defined (errno) -extern int errno; +extern int errno; #endif /* !errno */ extern int indirection_level, subshell_environment; @@ -494,7 +494,7 @@ get_exitstat (list) list = list->next; if (list == 0) - return (last_command_exit_value); + return (last_command_exit_value); arg = list->word->word; if (arg == 0 || legal_number (arg, &sval) == 0) @@ -760,7 +760,7 @@ display_signal_list (list, forcecols) list = list->next; continue; } -#if defined (JOB_CONTROL) && defined(HAVE_KILL_BUILTIN) +#if defined (JOB_CONTROL) /* POSIX.2 says that `kill -l signum' prints the signal name without the `SIG' prefix. */ printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name); @@ -771,10 +771,8 @@ display_signal_list (list, forcecols) else { dflags = DSIG_NOCASE; -#if defined(HAVE_KILL_BUILTIN) if (posixly_correct == 0 || this_shell_builtin != kill_builtin) dflags |= DSIG_SIGPREFIX; -#endif signum = decode_signal (list->word->word, dflags); if (signum == NO_SIG) { @@ -869,7 +867,7 @@ find_special_builtin (name) current_builtin->function : (sh_builtin_func_t *)NULL); } - + static int shell_builtin_compare (sbp1, sbp2) struct builtin *sbp1, *sbp2; diff --git a/src/bin/bash/builtins/kill.def b/src/bin/bash/builtins/kill.def index 4cff928360..d4a415bd2d 100644 --- a/src/bin/bash/builtins/kill.def +++ b/src/bin/bash/builtins/kill.def @@ -22,7 +22,6 @@ $PRODUCES kill.c $BUILTIN kill $FUNCTION kill_builtin -$DEPENDS_ON HAVE_KILL_BUILTIN $SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec] Send a signal to a job. @@ -55,6 +54,8 @@ $END # include #endif +#include + #include "../bashansi.h" #include "../bashintl.h" @@ -78,6 +79,46 @@ static void kill_error __P((pid_t, int)); # define CONTINUE_OR_FAIL goto continue_killing #endif /* CONTINUE_AFTER_KILL_ERROR */ + +int kill_by_name(int signum, const char *name) +{ + team_info teamInfo; + uint32 cookie = 0; + int status = EXECUTION_SUCCESS; + int found = 0; + + while (get_next_team_info(&cookie, &teamInfo) >= B_OK) { + char *token, *args; + + args = teamInfo.args; + token = strchr(args, ' '); + if (token) { + /* remove process argument */ + *token = 0; + } + + /* skip the path if any */ + token = basename(args); + + if (!strncmp(name, token, strlen(token))) { + found = 1; + /* name matched */ + if (kill((pid_t)teamInfo.team, signum) != 0) { + kill_error (teamInfo.team, errno); + status = EXECUTION_FAILURE; + } + } + } + + if (!found) + builtin_error (_("(%s) - %s"), name, strerror(ESRCH)); + + return status; +} + + + + /* Here is the kill builtin. We only have it so that people can type kill -KILL %1? No, if you fill up the process table this way you can still kill some. */ @@ -177,20 +218,27 @@ kill_builtin (list) word++; /* Use the entire argument in case of minus sign presence. */ - if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value)) - { - pid = (pid_t) pid_value; + if (*word) + { + if (legal_number (list->word->word, &pid_value) + && (pid_value == (pid_t)pid_value)) + { + pid = (pid_t) pid_value; - if (kill_pid (pid, sig, pid < -1) < 0) - { - if (errno == EINVAL) - sh_invalidsig (sigspec); - else - kill_error (pid, errno); - CONTINUE_OR_FAIL; - } - else - any_succeeded++; + if (kill_pid (pid, sig, pid < -1) < 0) + { + if (errno == EINVAL) + sh_invalidsig (sigspec); + else + kill_error (pid, errno); + CONTINUE_OR_FAIL; + } + else + any_succeeded++; + } else { + errno = kill_by_name(sig, word); + CONTINUE_OR_FAIL; + } } #if defined (JOB_CONTROL) else if (*list->word->word && *list->word->word != '%') diff --git a/src/bin/bash/lib/readline/Jamfile b/src/bin/bash/lib/readline/Jamfile index f9218da6c2..178e35541a 100644 --- a/src/bin/bash/lib/readline/Jamfile +++ b/src/bin/bash/lib/readline/Jamfile @@ -8,7 +8,7 @@ TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS) SubDirCcFlags -DHAVE_CONFIG_H -DSHELL ; -UseLibraryHeaders termcap ; +UseLibraryHeaders ncurses ; SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) include ] ; diff --git a/src/bin/bfs_tools/bfsinfo.cpp b/src/bin/bfs_tools/bfsinfo.cpp index 4c9a565daf..306b709eac 100644 --- a/src/bin/bfs_tools/bfsinfo.cpp +++ b/src/bin/bfs_tools/bfsinfo.cpp @@ -79,7 +79,7 @@ dump_indirect_stream(Disk &disk, bfs_inode *node, bool showOffsets) if (runs[i].IsZero()) return; - printf(" indirect[%02" B_PRId32 "] = ", i); + printf(" indirect[%04" B_PRId32 "] = ", i); char buffer[256]; if (showOffsets) @@ -94,6 +94,68 @@ dump_indirect_stream(Disk &disk, bfs_inode *node, bool showOffsets) } +void +dump_double_indirect_stream(Disk& disk, bfs_inode* node, bool showOffsets) +{ + if (node->data.max_double_indirect_range == 0) + return; + + int32 bytes = node->data.double_indirect.length * disk.BlockSize(); + int32 count = bytes / sizeof(block_run); + block_run runs[count]; + + off_t offset = node->data.max_indirect_range; + + ssize_t bytesRead = disk.ReadAt(disk.ToOffset(node->data.double_indirect), + (uint8*)runs, bytes); + if (bytesRead < bytes) { + fprintf(stderr, "couldn't read double indirect runs: %s\n", + strerror(bytesRead)); + return; + } + + puts("double indirect stream:"); + + for (int32 i = 0; i < count; i++) { + if (runs[i].IsZero()) + return; + + printf(" double_indirect[%02" B_PRId32 "] = ", i); + + dump_block_run("", runs[i], ""); + + int32 indirectBytes = runs[i].length * disk.BlockSize(); + int32 indirectCount = indirectBytes / sizeof(block_run); + block_run indirectRuns[indirectCount]; + + bytesRead = disk.ReadAt(disk.ToOffset(runs[i]), (uint8*)indirectRuns, + indirectBytes); + if (bytesRead < indirectBytes) { + fprintf(stderr, "couldn't read double indirect runs: %s\n", + strerror(bytesRead)); + continue; + } + + for (int32 j = 0; j < indirectCount; j++) { + if (indirectRuns[j].IsZero()) + break; + + printf(" [%04" B_PRId32 "] = ", j); + + char buffer[256]; + if (showOffsets) + snprintf(buffer, sizeof(buffer), " %16" B_PRIdOFF, offset); + else + buffer[0] = '\0'; + + dump_block_run("", indirectRuns[j], buffer); + + offset += indirectRuns[j].length * disk.BlockSize(); + } + } +} + + block_run parseBlockRun(Disk &disk, char *first, char *last) { @@ -235,6 +297,7 @@ main(int argc, char **argv) } char buffer[disk.BlockSize()]; + bfs_inode* bfsInode = (bfs_inode*)buffer; block_run run; Inode *inode = NULL; @@ -253,7 +316,7 @@ main(int argc, char **argv) return -1; } - inode = Inode::Factory(&disk, (bfs_inode *)buffer, false); + inode = Inode::Factory(&disk, bfsInode, false); if (inode == NULL || inode->InitCheck() < B_OK) { fprintf(stderr,"Not a valid inode!\n"); delete inode; @@ -264,13 +327,14 @@ main(int argc, char **argv) if (dumpInode) { printf("Inode at block %" B_PRIdOFF ":\n------------------------------" "-----------\n", disk.ToBlock(run)); - dump_inode(inode, (bfs_inode *)buffer, showOffsets); - dump_indirect_stream(disk, (bfs_inode *)buffer, showOffsets); + dump_inode(inode, bfsInode, showOffsets); + dump_indirect_stream(disk, bfsInode, showOffsets); + dump_double_indirect_stream(disk, bfsInode, showOffsets); dump_small_data(inode); putchar('\n'); } - if (dumpBTree && inode) { + if (dumpBTree && inode != NULL) { printf("B+Tree at block %" B_PRIdOFF ":\n-----------------------------" "------------\n", disk.ToBlock(run)); if (inode->IsDirectory() || inode->IsAttributeDirectory()) { @@ -280,7 +344,7 @@ main(int argc, char **argv) fprintf(stderr, "Inode is not a directory!\n"); } - if (validateBTree && inode) { + if (validateBTree && inode != NULL) { printf("Validating B+Tree at block %" B_PRIdOFF ":\n------------------" "-----------------------\n", disk.ToBlock(run)); if (inode->IsDirectory() || inode->IsAttributeDirectory()) { diff --git a/src/bin/coreutils/src/kill.c b/src/bin/coreutils/src/kill.c index f65b0cad12..dab4fa834e 100644 --- a/src/bin/coreutils/src/kill.c +++ b/src/bin/coreutils/src/kill.c @@ -21,7 +21,6 @@ #include #include #include -#include #if HAVE_SYS_WAIT_H # include @@ -37,7 +36,6 @@ #include "error.h" #include "sig2str.h" #include "operand2sig.h" -#include "OS.h" /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "kill" @@ -87,7 +85,7 @@ usage (int status) else { printf (_("\ -Usage: %s [-s SIGNAL | -SIGNAL] ...\n\ +Usage: %s [-s SIGNAL | -SIGNAL] PID...\n\ or: %s -l [SIGNAL]...\n\ or: %s -t [SIGNAL]...\n\ "), @@ -111,8 +109,6 @@ Mandatory arguments to long options are mandatory for short options too.\n\ SIGNAL may be a signal name like `HUP', or a signal number like `1',\n\ or the exit status of a process terminated by a signal.\n\ PID is an integer; if negative it identifies a process group.\n\ -PROCESS is name of the process to be killed. The signal will be sent \n\ -to all of the processes matching the given PROCESS name.\n\ "), stdout); printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME); emit_ancillary_info (); @@ -200,115 +196,38 @@ list_signals (bool table, char *const *argv) return status; } - - -/* - * Checks if passed string is a valid number - * - * Returns: - * true: on valid number - * The converted number is returned in NUM if it is not NULL - * - * false: on invalid number - * - */ -bool is_number(const char *str, intmax_t *_number) -{ - char *end; - intmax_t number; - - if (!str) - return 0; - - errno = 0; - number = strtoimax(str, &end, 10); - if (errno == ERANGE || str == end) { - /* not a valid number */ - return false; - } - - /* skip all whitespace if there are any */ - while (*end == ' ' || *end == '\t') - end++; - - if (*end == '\0') { - if (_number) - *_number = number; - return true; - } - return false; -} - - -/* - * kill the processes if they match given name - * - * Returns EXIT_SUCCESS signal was successfully sent to all matched processes, - * otherwise EXIT_FAILURE is returned. - */ -int kill_by_name(int signum, const char *name) -{ - team_info teamInfo; - uint32 cookie = 0; - int status = EXIT_SUCCESS; - int found = 0; - - while (get_next_team_info(&cookie, &teamInfo) >= B_OK) { - char *token, *args; - - args = teamInfo.args; - token = strchr(args, ' '); - if (token) { - /* remove process argument */ - *token = 0; - } - - /* skip the path if any */ - token = basename(args); - - if (!strncmp(name, token, strlen(token))) { - found = 1; - /* name matched */ - if (kill((pid_t)teamInfo.team, signum) != 0) { - error (0, errno, "%s", name); - status = EXIT_FAILURE; - } - } - } - - if (!found) - error (0, ESRCH, "%s", name); - - return status; -} - - + /* Send signal SIGNUM to all the processes or process groups specified by ARGV. Return a suitable exit status. */ static int send_signals (int signum, char *const *argv) { - int status = EXIT_SUCCESS; - char const *arg = *argv; - pid_t pid; + int status = EXIT_SUCCESS; + char const *arg = *argv; - do { - bool is_pid = is_number(arg, (intmax_t *) &pid); - if (is_pid) { - if (kill(pid, signum) != 0) { - error (0, errno, "%s", arg); - status = EXIT_FAILURE; - } - } else if (kill_by_name(signum, arg) != EXIT_SUCCESS) - status = EXIT_FAILURE; + do + { + char *endp; + intmax_t n = (errno = 0, strtoimax (arg, &endp, 10)); + pid_t pid = n; - } while ((arg = *++argv)); + if (errno == ERANGE || pid != n || arg == endp || *endp) + { + error (0, 0, _("%s: invalid process id"), arg); + status = EXIT_FAILURE; + } + else if (kill (pid, signum) != 0) + { + error (0, errno, "%s", arg); + status = EXIT_FAILURE; + } + } + while ((arg = *++argv)); - return status; + return status; } - - + int main (int argc, char **argv) { diff --git a/src/bin/debug/debug_utils.cpp b/src/bin/debug/debug_utils.cpp index fa9d431b43..e91bf36ace 100644 --- a/src/bin/debug/debug_utils.cpp +++ b/src/bin/debug/debug_utils.cpp @@ -1,5 +1,6 @@ /* * Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -116,52 +117,52 @@ load_program(const char* const* args, int32 argCount, bool traceLoading) // set_team_debugging_flags -void +status_t set_team_debugging_flags(port_id nubPort, int32 flags) { debug_nub_set_team_flags message; message.flags = flags; - while (true) { - status_t error = write_port(nubPort, B_DEBUG_MESSAGE_SET_TEAM_FLAGS, + status_t error = B_OK; + do { + error = write_port(nubPort, B_DEBUG_MESSAGE_SET_TEAM_FLAGS, &message, sizeof(message)); - if (error == B_OK) - return; + } while (error == B_INTERRUPTED); - if (error != B_INTERRUPTED) { - fprintf(stderr, "%s: Failed to set team debug flags: %s\n", - kCommandName, strerror(error)); - exit(1); - } + if (error != B_OK) { + fprintf(stderr, "%s: Failed to set team debug flags: %s\n", + kCommandName, strerror(error)); } + + return error; } // set_thread_debugging_flags -void +status_t set_thread_debugging_flags(port_id nubPort, thread_id thread, int32 flags) { debug_nub_set_thread_flags message; message.thread = thread; message.flags = flags; - while (true) { - status_t error = write_port(nubPort, B_DEBUG_MESSAGE_SET_THREAD_FLAGS, + status_t error = B_OK; + do { + error = write_port(nubPort, B_DEBUG_MESSAGE_SET_THREAD_FLAGS, &message, sizeof(message)); - if (error == B_OK) - return; + } while (error == B_INTERRUPTED); - if (error != B_INTERRUPTED) { - fprintf(stderr, "%s: Failed to set thread debug flags: %s\n", - kCommandName, strerror(error)); - exit(1); - } + if (error != B_OK) { + fprintf(stderr, "%s: Failed to set thread debug flags: %s\n", + kCommandName, strerror(error)); } + + return error; } // continue_thread -void +status_t continue_thread(port_id nubPort, thread_id thread) { debug_nub_continue_thread message; @@ -169,16 +170,17 @@ continue_thread(port_id nubPort, thread_id thread) message.handle_event = B_THREAD_DEBUG_HANDLE_EVENT; message.single_step = false; - while (true) { - status_t error = write_port(nubPort, B_DEBUG_MESSAGE_CONTINUE_THREAD, - &message, sizeof(message)); - if (error == B_OK) - return; + status_t error = B_OK; - if (error != B_INTERRUPTED) { - fprintf(stderr, "%s: Failed to run thread %" B_PRId32 ": %s\n", - kCommandName, thread, strerror(error)); - exit(1); - } + do { + error = write_port(nubPort, B_DEBUG_MESSAGE_CONTINUE_THREAD, + &message, sizeof(message)); + } while (error == B_INTERRUPTED); + + if (error != B_OK) { + fprintf(stderr, "%s: Failed to run thread %" B_PRId32 ": %s\n", + kCommandName, thread, strerror(error)); } + + return error; } diff --git a/src/bin/debug/debug_utils.h b/src/bin/debug/debug_utils.h index 0228360de8..b4c4f67f9e 100644 --- a/src/bin/debug/debug_utils.h +++ b/src/bin/debug/debug_utils.h @@ -11,10 +11,10 @@ thread_id load_program(const char* const* args, int32 argCount, bool traceLoading); -void set_team_debugging_flags(port_id nubPort, int32 flags); -void set_thread_debugging_flags(port_id nubPort, thread_id thread, +status_t set_team_debugging_flags(port_id nubPort, int32 flags); +status_t set_thread_debugging_flags(port_id nubPort, thread_id thread, int32 flags); -void continue_thread(port_id nubPort, thread_id thread); +status_t continue_thread(port_id nubPort, thread_id thread); #endif // BIN_DEBUG_DEBUG_UTILS_H diff --git a/src/bin/debug/profile/Team.cpp b/src/bin/debug/profile/Team.cpp index 331b28e9dd..433fde1269 100644 --- a/src/bin/debug/profile/Team.cpp +++ b/src/bin/debug/profile/Team.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -86,7 +87,9 @@ Team::Init(team_id teamID, port_id debuggerPort) // set team debugging flags int32 teamDebugFlags = B_TEAM_DEBUG_THREADS | B_TEAM_DEBUG_TEAM_CREATION | B_TEAM_DEBUG_IMAGES; - set_team_debugging_flags(fNubPort, teamDebugFlags); + error = set_team_debugging_flags(fNubPort, teamDebugFlags); + if (error != B_OK) + return error; return B_OK; } @@ -138,7 +141,10 @@ Team::InitThread(Thread* thread) // | (traceChildThreads // ? B_THREAD_DEBUG_SYSCALL_TRACE_CHILD_THREADS : 0); // } - set_thread_debugging_flags(fNubPort, thread->ID(), threadDebugFlags); + status_t error = set_thread_debugging_flags(fNubPort, thread->ID(), + threadDebugFlags); + if (error != B_OK) + return error; // start profiling debug_nub_start_profiler message; @@ -150,7 +156,7 @@ Team::InitThread(Thread* thread) message.variable_stack_depth = gOptions.analyze_full_stack; debug_nub_start_profiler_reply reply; - status_t error = send_debug_message(&fDebugContext, + error = send_debug_message(&fDebugContext, B_DEBUG_START_PROFILER, &message, sizeof(message), &reply, sizeof(reply)); if (error != B_OK || (error = reply.error) != B_OK) { diff --git a/src/bin/debug/profile/profile.cpp b/src/bin/debug/profile/profile.cpp index dd50dcd81e..22f6338be3 100644 --- a/src/bin/debug/profile/profile.cpp +++ b/src/bin/debug/profile/profile.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -542,7 +543,8 @@ process_event_buffer(ThreadManager& threadManager, uint8* buffer, system_profiler_team_added* event = (system_profiler_team_added*)buffer; - threadManager.AddTeam(event); + if (threadManager.AddTeam(event) != B_OK) + exit(1); break; } @@ -575,8 +577,10 @@ process_event_buffer(ThreadManager& threadManager, uint8* buffer, system_profiler_thread_added* event = (system_profiler_thread_added*)buffer; - threadManager.AddThread(event->team, event->thread, - event->name); + if (threadManager.AddThread(event->team, event->thread, + event->name) != B_OK) { + exit(1); + } break; } diff --git a/src/bin/debug/strace/strace.cpp b/src/bin/debug/strace/strace.cpp index 046efbdf13..a232a9c101 100644 --- a/src/bin/debug/strace/strace.cpp +++ b/src/bin/debug/strace/strace.cpp @@ -1,5 +1,6 @@ /* * Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -144,7 +145,8 @@ struct Team { int32 teamDebugFlags = (traceTeam ? B_TEAM_DEBUG_POST_SYSCALL : 0) | (traceChildTeams ? B_TEAM_DEBUG_TEAM_CREATION : 0) | (traceSignal ? B_TEAM_DEBUG_SIGNALS : 0); - set_team_debugging_flags(fNubPort, teamDebugFlags); + if (set_team_debugging_flags(fNubPort, teamDebugFlags) != B_OK) + exit(1); return fMemoryReader.Init(fNubPort); } @@ -568,7 +570,10 @@ main(int argc, const char *const *argv) | (traceChildThreads ? B_THREAD_DEBUG_SYSCALL_TRACE_CHILD_THREADS : 0); } - set_thread_debugging_flags(nubPort, threadID, threadDebugFlags); + if (set_thread_debugging_flags(nubPort, threadID, threadDebugFlags) + != B_OK) { + exit(1); + } // resume the target thread to be sure, it's running resume_thread(threadID); @@ -672,8 +677,12 @@ main(int argc, const char *const *argv) // tell the thread to continue (only when there is a thread and the // message was synchronous) - if (message.origin.thread >= 0 && message.origin.nub_port >= 0) - continue_thread(message.origin.nub_port, message.origin.thread); + if (message.origin.thread >= 0 && message.origin.nub_port >= 0) { + if (continue_thread(message.origin.nub_port, + message.origin.thread) != B_OK) { + exit(1); + } + } } if (outputFile != NULL && outputFile != stdout) diff --git a/src/bin/less/Jamfile b/src/bin/less/Jamfile index 9c5c97cd85..7553613556 100644 --- a/src/bin/less/Jamfile +++ b/src/bin/less/Jamfile @@ -6,14 +6,14 @@ TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS) SubDirCcFlags -DBINDIR='\"/bin\"' -DSYSDIR='\"/etc\"' ; -UseLibraryHeaders termcap ; +UseLibraryHeaders ncurses ; SubDirSysHdrs $(SUBDIR) ; BinCommand less : main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c decode.c edit.c filename.c forwback.c help.c ifile.c input.c jump.c line.c linenum.c lsystem.c mark.c optfunc.c option.c opttbl.c os.c output.c position.c prompt.c search.c signal.c tags.c ttyin.c version.c : - libtermcap.a : less.rdef ; + libncurses.a : less.rdef ; BinCommand lesskey : lesskey.c version.c : : less.rdef ; diff --git a/src/bin/network/route/route.cpp b/src/bin/network/route/route.cpp index 9989d0380a..ca2c310718 100644 --- a/src/bin/network/route/route.cpp +++ b/src/bin/network/route/route.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2013, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de + * Alexander von Gluck */ @@ -39,37 +40,35 @@ enum modes { RTM_FLUSH, }; -enum preferred_output_format { - PREFER_OUTPUT_MASK, - PREFER_OUTPUT_PREFIX_LENGTH, +enum preferredPrefixFormat { + PREFIX_PREFER_NETMASK = 0, + PREFIX_PREFER_CIDR, }; struct address_family { int family; const char* name; const char* identifiers[4]; - preferred_output_format preferred_format; - bool (*parse_address)(const char* string, sockaddr* _address); - bool (*prefix_length_to_mask)(uint8 prefixLength, sockaddr* mask); - uint8 (*mask_to_prefix_length)(sockaddr* mask); - const char* (*address_to_string)(sockaddr* address); + int maxAddressLength; + int preferredPrefixFormat; }; - static const address_family kFamilies[] = { { AF_INET, - "inet", + "IPv4", {"AF_INET", "inet", "ipv4", NULL}, - PREFER_OUTPUT_MASK, + 15, + PREFIX_PREFER_NETMASK, }, { AF_INET6, - "inet6", + "IPv6", {"AF_INET6", "inet6", "ipv6", NULL}, - PREFER_OUTPUT_PREFIX_LENGTH, + 39, + PREFIX_PREFER_CIDR, }, - { -1, NULL, {NULL}, PREFER_OUTPUT_MASK, NULL, NULL, NULL, NULL } + { -1, NULL, {NULL}, -1, -1 } }; @@ -187,75 +186,91 @@ list_routes(int socket, const char *interfaceName, route_entry &route) ifreq *interface = (ifreq*)buffer; ifreq *end = (ifreq*)((uint8*)buffer + size); + // find family (we use the family of the first address as this is + // called on a socket for a single family) + const address_family *family = NULL; + for (int32 i = 0; kFamilies[i].family >= 0; i++) { + if (interface->ifr_route.destination->sa_family + == kFamilies[i].family) { + family = &kFamilies[i]; + break; + } + } + + int addressLength = family->maxAddressLength; + + printf("%s routing table:\n", family->name); + + if (family->preferredPrefixFormat == PREFIX_PREFER_NETMASK) { + printf("%*s %*s %*s Flags Interface\n", addressLength, "Destination", + addressLength, "Netmask", addressLength, "Gateway"); + } else { + printf("%*s %*s Flags Interface\n", addressLength, "Destination", + addressLength, "Gateway"); + } + while (interface < end) { route_entry& route = interface->ifr_route; // apply filters if (interfaceName == NULL || !strcmp(interfaceName, interface->ifr_name)) { - // find family - const address_family *family = NULL; - for (int32 i = 0; kFamilies[i].family >= 0; i++) { - if (route.destination->sa_family == kFamilies[i].family) { - family = &kFamilies[i]; - break; - } - } if (family != NULL) { BNetworkAddress destination(*route.destination); - BNetworkAddress mask; - if (route.mask != NULL) + printf("%*s", addressLength, destination.ToString().String()); + if (route.mask != NULL) { + BNetworkAddress mask; mask.SetTo(*route.mask); - - // TODO: is the %15s format OK for IPv6? - printf("%15s", destination.ToString().String()); - switch (family->preferred_format) { - case PREFER_OUTPUT_MASK: - printf(" mask %-15s ", mask.ToString().String()); - break; - case PREFER_OUTPUT_PREFIX_LENGTH: - printf("/%zd ", mask.PrefixLength()); - break; + if (family->preferredPrefixFormat + == PREFIX_PREFER_NETMASK) { + printf(" %*s ", addressLength, + mask.ToString().String()); + } else { + printf("/%-3zd ", mask.PrefixLength()); + } + } else { + if (family->preferredPrefixFormat + == PREFIX_PREFER_NETMASK) { + printf(" %*s ", addressLength, "-"); + } else + printf(" "); } + if ((route.flags & RTF_GATEWAY) != 0) { BNetworkAddress gateway; if (route.gateway != NULL) gateway.SetTo(*route.gateway); - printf("gateway %-15s ", gateway.ToString().String()); - } + printf("%*s ", addressLength, gateway.ToString().String()); + } else + printf("%*s ", family->maxAddressLength, "-"); } else printf("unknown family "); - printf("%s", interface->ifr_name); - if (route.flags != 0) { const struct { int value; const char *name; } kFlags[] = { - {RTF_DEFAULT, "default"}, - {RTF_REJECT, "reject"}, - {RTF_HOST, "host"}, - {RTF_LOCAL, "local"}, - {RTF_DYNAMIC, "dynamic"}, - {RTF_MODIFIED, "modified"}, + {RTF_DEFAULT, "D"}, + {RTF_REJECT, "R"}, + {RTF_HOST, "H"}, + {RTF_LOCAL, "L"}, + {RTF_DYNAMIC, "D"}, + {RTF_MODIFIED, "M"}, }; - bool first = true; - for (uint32 i = 0; i < sizeof(kFlags) / sizeof(kFlags[0]); - i++) { + i++) { if ((route.flags & kFlags[i].value) != 0) { - if (first) { - printf(", "); - first = false; - } else - putchar(' '); printf(kFlags[i].name); - } + } else + putchar('-'); } - } + printf(" "); + } else + printf("------ "); + printf("%s", interface->ifr_name); putchar('\n'); } @@ -271,6 +286,7 @@ list_routes(int socket, const char *interfaceName, route_entry &route) + sizeof(route_entry) + addressSize); } + putchar('\n'); free(buffer); } @@ -334,22 +350,17 @@ get_route(int socket, route_entry &route) } if (family != NULL) { - printf("%s", family->address_to_string(request.destination)); - switch (family->preferred_format) { - case PREFER_OUTPUT_MASK: - printf(" mask %s ", - family->address_to_string(request.mask)); - break; - case PREFER_OUTPUT_PREFIX_LENGTH: - printf("/%u ", - family->mask_to_prefix_length(request.mask)); - break; - } + BNetworkAddress destination(*request.destination); + BNetworkAddress mask(*request.mask); + printf("%s", destination.ToString().String()); + printf("/%zd ", mask.PrefixLength()); + BNetworkAddress gateway(*request.gateway); if (request.flags & RTF_GATEWAY) - printf("gateway %s ", family->address_to_string(request.gateway)); + printf("gateway %s ", gateway.ToString().String()); - printf("source %s\n", family->address_to_string(request.source)); + BNetworkAddress source(*request.source); + printf("source %s\n", source.ToString().String()); } else { printf("unknown family "); } diff --git a/src/bin/network/telnet/Jamfile b/src/bin/network/telnet/Jamfile index 67604b72ca..66595aad9d 100644 --- a/src/bin/network/telnet/Jamfile +++ b/src/bin/network/telnet/Jamfile @@ -20,5 +20,5 @@ BinCommand telnet : telnet.c terminal.c utilities.c - : libtermcap.a libncurses.a libtelnet.a libutil.a libbsd.so $(TARGET_NETWORK_LIBS) + : libncurses.a libtelnet.a libutil.a libbsd.so $(TARGET_NETWORK_LIBS) ; diff --git a/src/bin/network/telnetd/Jamfile b/src/bin/network/telnetd/Jamfile index 13e1238a64..ad3e460948 100644 --- a/src/bin/network/telnetd/Jamfile +++ b/src/bin/network/telnetd/Jamfile @@ -1,6 +1,6 @@ SubDir HAIKU_TOP src bin network telnetd ; -UseLibraryHeaders termcap ; +UseLibraryHeaders ncurses ; UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) src libs ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) src libs libtelnet ] : false ; @@ -19,5 +19,5 @@ BinCommand telnetd : telnetd.c termstat.c utility.c - : libtermcap.a libtelnet.a libutil.a libbsd.so $(TARGET_NETWORK_LIBS) + : libncurses.a libtelnet.a libutil.a libbsd.so $(TARGET_NETWORK_LIBS) ; diff --git a/src/bin/tput.c b/src/bin/tput.c deleted file mode 100644 index 1289959a04..0000000000 --- a/src/bin/tput.c +++ /dev/null @@ -1,235 +0,0 @@ -/* $NetBSD: tput.c,v 1.15 2003/08/07 11:16:46 agc Exp $ */ - -/*- - * Copyright (c) 1980, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 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. - */ - -//#include -#define __P(x) x -#ifndef lint -static char copyright[] ="@(#) Copyright (c) 1980, 1988, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)tput.c 8.3 (Berkeley) 4/28/95"; -#endif -static char rcsid[] = "$NetBSD: tput.c,v 1.15 2003/08/07 11:16:46 agc Exp $"; -#endif /* not lint */ - -#include - -//#include -#include -#include -#include -#include -#include - - int main __P((int, char **)); -static int outc __P((int)); -static void prlongname __P((char *)); -static void setospeed __P((void)); -static void usage __P((void)); -static char **process __P((char *, char *, char **)); - -int -main(argc, argv) - int argc; - char **argv; -{ - int ch, exitval, n; - char *cptr, *p, *term, buf[1024], tbuf[1024]; - - term = NULL; - while ((ch = getopt(argc, argv, "T:")) != -1) - switch(ch) { - case 'T': - term = optarg; - break; - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - if (!term && !(term = getenv("TERM"))) - fprintf(stderr, "no terminal type specified and no TERM environmental variable."); - if (tgetent(tbuf, term) != 1) - fprintf(stderr, "tgetent failure"); - setospeed(); - for (exitval = 0; (p = *argv) != NULL; ++argv) { - switch (*p) { - case 'c': - if (!strcmp(p, "clear")) - p = "cl"; - break; - case 'i': - if (!strcmp(p, "init")) - p = "is"; - break; - case 'l': - if (!strcmp(p, "longname")) { - prlongname(tbuf); - continue; - } - break; - case 'r': - if (!strcmp(p, "reset")) - p = "rs"; - break; - } - cptr = buf; - if (tgetstr(p, &cptr)) - argv = process(p, buf, argv); - else if ((n = tgetnum(p)) != -1) - (void)printf("%d\n", n); - else - exitval = !tgetflag(p); - - if (argv == NULL) - break; - } - exit(argv ? exitval : 2); -} - -static void -prlongname(buf) - char *buf; -{ - int savech; - char *p, *savep; - - for (p = buf; *p && *p != ':'; ++p) - continue; - savech = *(savep = p); - for (*p = '\0'; p >= buf && *p != '|'; --p) - continue; - (void)printf("%s\n", p + 1); - *savep = savech; -} - -static char ** -process(cap, str, argv) - char *cap, *str, **argv; -{ - static const char errfew[] = - "not enough arguments (%d) for capability `%s'"; - static const char errmany[] = - "too many arguments (%d) for capability `%s'"; - static const char erresc[] = - "unknown %% escape `%c' for capability `%s'"; - char *cp; - int arg_need, arg_rows, arg_cols; - - /* Count how many values we need for this capability. */ - for (cp = str, arg_need = 0; *cp != '\0'; cp++) - if (*cp == '%') - switch (*++cp) { - case 'd': - case '2': - case '3': - case '.': - case '+': - arg_need++; - break; - case '%': - case '>': - case 'i': - case 'r': - case 'n': - case 'B': - case 'D': - break; - default: - /* - * hpux has lot's of them, but we complain - */ - fprintf(stderr, erresc, *cp, cap); - } - - /* And print them. */ - switch (arg_need) { - case 0: - (void)tputs(str, 1, outc); - break; - case 1: - arg_cols = 0; - - if (*++argv == NULL || *argv[0] == '\0') - fprintf(stderr, errfew); - arg_rows = atoi(*argv); - - (void)tputs(tgoto(str, arg_cols, arg_rows), 1, outc); - break; - case 2: - if (*++argv == NULL || *argv[0] == '\0') - fprintf(stderr, errfew); - arg_rows = atoi(*argv); - - if (*++argv == NULL || *argv[0] == '\0') - fprintf(stderr, errfew); - arg_cols = atoi(*argv); - - (void) tputs(tgoto(str, arg_cols, arg_rows), arg_rows, outc); - break; - - default: - fprintf(stderr, errmany); - } - return (argv); -} - -static void -setospeed() -{ -#undef ospeed - extern short ospeed; - struct termios t; - - if (tcgetattr(STDOUT_FILENO, &t) != -1) - ospeed = 0; - else - ospeed = cfgetospeed(&t); -} - -static int -outc(c) - int c; -{ - return (putchar(c)); -} - -static void -usage() -{ - (void)fprintf(stderr, "usage: tput [-T term] attribute ...\n"); - exit(1); -} diff --git a/src/kits/Jamfile b/src/kits/Jamfile index 4c23f532ad..d642ea29b7 100644 --- a/src/kits/Jamfile +++ b/src/kits/Jamfile @@ -17,7 +17,7 @@ if $(RUN_WITHOUT_APP_SERVER) != 0 { SubDirC++Flags $(defines) ; } -UsePrivateHeaders app interface kernel locale shared ; +UsePrivateHeaders app interface kernel locale print shared ; # Build our libbe.so @@ -64,15 +64,9 @@ SharedLibrary libbe_test.so : $(TARGET_LIBSTDC++) ; -SEARCH on [ FGristFiles AboutMenuItem.cpp ] += [ FDirName $(HAIKU_TOP) src kits shared ] ; -SEARCH on [ FGristFiles AboutWindow.cpp ] += [ FDirName $(HAIKU_TOP) src kits shared ] ; -SEARCH on [ FGristFiles ColorControl.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; -SEARCH on [ FGristFiles StringForSize.cpp ] += [ FDirName $(HAIKU_TOP) src kits shared ] ; -SEARCH on [ FGristFiles TextView.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; -SEARCH on [ FGristFiles Dragger.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; -SEARCH on [ FGristFiles Menu.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; -SEARCH on [ FGristFiles PrintJob.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; -SEARCH on [ FGristFiles ZombieReplicantView.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) interface ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) interface textview_support ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) shared ] ; DoCatalogs libbe.so : x-vnd.Haiku-libbe diff --git a/src/kits/interface/BMCPrivate.cpp b/src/kits/interface/BMCPrivate.cpp index f1dde0267d..e46eef58c0 100644 --- a/src/kits/interface/BMCPrivate.cpp +++ b/src/kits/interface/BMCPrivate.cpp @@ -11,6 +11,8 @@ #include +#include + #include #include #include @@ -20,10 +22,6 @@ #include -static const float kPopUpIndicatorWidth = 10.0f; -static const float kMarginWidth = 3.0f; - - _BMCFilter_::_BMCFilter_(BMenuField* menuField, uint32 what) : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, what), @@ -57,6 +55,9 @@ _BMCFilter_::Filter(BMessage* message, BHandler** handler) // #pragma mark - +static const float kPopUpIndicatorWidth = 13.0f; + + _BMCMenuBar_::_BMCMenuBar_(BRect frame, bool fixedSize, BMenuField* menuField) : BMenuBar(frame, "_mc_mb_", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_ITEMS_IN_ROW, @@ -66,7 +67,7 @@ _BMCMenuBar_::_BMCMenuBar_(BRect frame, bool fixedSize, BMenuField* menuField) fRunner(NULL), fShowPopUpMarker(true) { - _Init(true); + _Init(); } @@ -78,7 +79,7 @@ _BMCMenuBar_::_BMCMenuBar_(BMenuField* menuField) fRunner(NULL), fShowPopUpMarker(true) { - _Init(false); + _Init(); } @@ -137,11 +138,22 @@ _BMCMenuBar_::AttachedToWindow() void _BMCMenuBar_::Draw(BRect updateRect) { - if (fFixedSize || Bounds().Width() > fMenuField->_MenuBarWidth()) { - // Set the width of the menu bar because the menu bar bounds have + if (fFixedSize) { + // Set the width of the menu bar because the menu bar bounds may have // been expanded by the selected menu item. ResizeTo(fMenuField->_MenuBarWidth(), Bounds().Height()); + } else { + // For compatability with BeOS R5: + // - Set to the minimum of the menu bar width set by the menu frame + // and the selected menu item width. + // - Set the height to the preferred height ignoring the height of the + // menu field. + float height; + BMenuBar::GetPreferredSize(NULL, &height); + ResizeTo(std::min(Bounds().Width(), fMenuField->_MenuBarWidth()), + height); } + BRect rect(Bounds()); rgb_color base = ui_color(B_MENU_BACKGROUND_COLOR); uint32 flags = 0; @@ -165,30 +177,29 @@ _BMCMenuBar_::FrameResized(float width, float height) float diff = width - fPreviousWidth; fPreviousWidth = width; - if (Window()) { + if (Window() != NULL && diff != 0) { + BRect dirty(fMenuField->Bounds()); if (diff > 0) { // clean up the dirty right border of // the menu field when enlarging - BRect dirty(fMenuField->Bounds()); - dirty.right = Frame().right + 2; - dirty.left = dirty.left - diff - 4; + dirty.right = Frame().right + kVMargin; + dirty.left = dirty.left - diff - kVMargin * 2; fMenuField->Invalidate(dirty); // clean up the arrow part dirty = Bounds(); - dirty.left = dirty.right - diff - 12; + dirty.left = dirty.right - diff - kPopUpIndicatorWidth; Invalidate(dirty); } else if (diff < 0) { // clean up the dirty right line of // the menu field when shrinking - BRect dirty(fMenuField->Bounds()); - dirty.left = Frame().right - 2; - dirty.right = dirty.left - diff + 4; + dirty.left = Frame().right - kVMargin; + dirty.right = dirty.left - diff + kVMargin * 2; fMenuField->Invalidate(dirty); // clean up the arrow part dirty = Bounds(); - dirty.left = dirty.right - 12; + dirty.left = dirty.right - kPopUpIndicatorWidth; Invalidate(dirty); } } @@ -254,6 +265,17 @@ _BMCMenuBar_::MakeFocus(bool focused) } +void +_BMCMenuBar_::SetMaxContentWidth(float width) +{ + float left; + float right; + GetItemMargins(&left, NULL, &right, NULL); + + BMenuBar::SetMaxContentWidth(width - (left + right)); +} + + BSize _BMCMenuBar_::MinSize() { @@ -262,7 +284,7 @@ _BMCMenuBar_::MinSize() if (fShowPopUpMarker) { // account for popup indicator + a few pixels margin - size.width += kPopUpIndicatorWidth + kMarginWidth; + size.width += kPopUpIndicatorWidth; } return BLayoutUtils::ComposeSize(ExplicitMinSize(), size); @@ -281,7 +303,7 @@ _BMCMenuBar_::MaxSize() void -_BMCMenuBar_::_Init(bool setMaxContentWidth) +_BMCMenuBar_::_Init() { SetFlags(Flags() | B_FRAME_EVENTS); SetBorder(B_BORDER_CONTENTS); @@ -309,11 +331,7 @@ _BMCMenuBar_::_Init(bool setMaxContentWidth) left = right = be_control_look->DefaultLabelSpacing(); SetItemMargins(left, top, - right + fShowPopUpMarker ? kPopUpIndicatorWidth + kMarginWidth : 0, - bottom); + right + fShowPopUpMarker ? kPopUpIndicatorWidth : 0, bottom); fPreviousWidth = Bounds().Width(); - - if (setMaxContentWidth) - SetMaxContentWidth(fPreviousWidth - (left + right)); } diff --git a/src/kits/interface/Box.cpp b/src/kits/interface/Box.cpp index a4a0165652..5f84ac6965 100644 --- a/src/kits/interface/Box.cpp +++ b/src/kits/interface/Box.cpp @@ -1,12 +1,13 @@ /* - * Copyright (c) 2001-2009, Haiku, Inc. + * Copyright 2001-2013 Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT license. * * Authors: - * Marc Flerackers (mflerackers@androme.be) - * Stephan Aßmus - * DarkWyrm + * Stephan Aßmus, superstippi@gmx.de + * DarkWyrm, bpmagic@columbus.rr.com * Axel Dörfler, axeld@pinc-software.de + * Marc Flerackers, mflerackers@androme.be + * John Scipione, jscipione@gmail.com */ @@ -37,13 +38,15 @@ struct BBox::LayoutData { BSize min; BSize max; BSize preferred; + BAlignment alignment; bool valid; // validity the other fields }; -BBox::BBox(BRect frame, const char *name, uint32 resizingMode, uint32 flags, +BBox::BBox(BRect frame, const char* name, uint32 resizingMode, uint32 flags, border_style border) - : BView(frame, name, resizingMode, flags | B_WILL_DRAW | B_FRAME_EVENTS), + : + BView(frame, name, resizingMode, flags | B_WILL_DRAW | B_FRAME_EVENTS), fStyle(border) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); @@ -54,8 +57,9 @@ BBox::BBox(BRect frame, const char *name, uint32 resizingMode, uint32 flags, BBox::BBox(const char* name, uint32 flags, border_style border, BView* child) - : BView(name, flags | B_WILL_DRAW | B_FRAME_EVENTS), - fStyle(border) + : + BView(name, flags | B_WILL_DRAW | B_FRAME_EVENTS), + fStyle(border) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); @@ -68,8 +72,9 @@ BBox::BBox(const char* name, uint32 flags, border_style border, BView* child) BBox::BBox(border_style border, BView* child) - : BView(NULL, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP), - fStyle(border) + : + BView(NULL, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP), + fStyle(border) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); @@ -81,9 +86,10 @@ BBox::BBox(border_style border, BView* child) } -BBox::BBox(BMessage *archive) - : BView(archive), - fStyle(B_FANCY_BORDER) +BBox::BBox(BMessage* archive) + : + BView(archive), + fStyle(B_FANCY_BORDER) { _InitObject(archive); } @@ -97,8 +103,8 @@ BBox::~BBox() } -BArchivable * -BBox::Instantiate(BMessage *archive) +BArchivable* +BBox::Instantiate(BMessage* archive) { if (validate_instantiation(archive, "BBox")) return new BBox(archive); @@ -108,7 +114,7 @@ BBox::Instantiate(BMessage *archive) status_t -BBox::Archive(BMessage *archive, bool deep) const +BBox::Archive(BMessage* archive, bool deep) const { status_t ret = BView::Archive(archive, deep); @@ -179,7 +185,7 @@ BBox::InnerFrame() void -BBox::SetLabel(const char *string) +BBox::SetLabel(const char* string) { _ClearLabel(); @@ -194,7 +200,7 @@ BBox::SetLabel(const char *string) status_t -BBox::SetLabel(BView *viewLabel) +BBox::SetLabel(BView* viewLabel) { _ClearLabel(); @@ -213,14 +219,14 @@ BBox::SetLabel(BView *viewLabel) } -const char * +const char* BBox::Label() const { return fLabel; } -BView * +BView* BBox::LabelView() const { return fLabelView; @@ -357,7 +363,7 @@ BBox::FrameResized(float width, float height) void -BBox::MessageReceived(BMessage *message) +BBox::MessageReceived(BMessage* message) { BView::MessageReceived(message); } @@ -385,7 +391,7 @@ BBox::WindowActivated(bool active) void -BBox::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +BBox::MouseMoved(BPoint point, uint32 transit, const BMessage* message) { BView::MouseMoved(point, transit, message); } @@ -398,10 +404,9 @@ BBox::FrameMoved(BPoint newLocation) } -BHandler * -BBox::ResolveSpecifier(BMessage *message, int32 index, - BMessage *specifier, int32 what, - const char *property) +BHandler* +BBox::ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier, + int32 what, const char* property) { return BView::ResolveSpecifier(message, index, specifier, what, property); } @@ -424,7 +429,7 @@ BBox::ResizeToPreferred() void -BBox::GetPreferredSize(float *_width, float *_height) +BBox::GetPreferredSize(float* _width, float* _height) { _ValidateLayoutData(); @@ -443,7 +448,7 @@ BBox::MakeFocus(bool focused) status_t -BBox::GetSupportedSuites(BMessage *message) +BBox::GetSupportedSuites(BMessage* message) { return BView::GetSupportedSuites(message); } @@ -480,7 +485,7 @@ BBox::Perform(perform_code code, void* _data) BBox::GetHeightForWidth(data->width, &data->min, &data->max, &data->preferred); return B_OK; -} + } case PERFORM_CODE_SET_LAYOUT: { perform_data_set_layout* data = (perform_data_set_layout*)_data; @@ -536,6 +541,17 @@ BBox::PreferredSize() } +BAlignment +BBox::LayoutAlignment() +{ + _ValidateLayoutData(); + + BAlignment alignment = (GetLayout() ? GetLayout()->Alignment() + : fLayoutData->alignment); + return BLayoutUtils::ComposeAlignment(ExplicitAlignment(), alignment); +} + + void BBox::LayoutInvalidated(bool descendants) { @@ -633,7 +649,7 @@ BBox::_InitObject(BMessage* archive) SetFont(&font, flags); if (archive != NULL) { - const char *string; + const char* string; if (archive->FindString("_label", &string) == B_OK) SetLabel(string); @@ -845,6 +861,8 @@ BBox::_ValidateLayoutData() else minWidth = addWidth - 1; + BAlignment alignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER); + // finally consider the child constraints, if we shall support layout BView* child = _Child(); if (child && (Flags() & B_SUPPORTS_LAYOUT)) { @@ -866,10 +884,19 @@ BBox::_ValidateLayoutData() fLayoutData->min = min; fLayoutData->max = max; fLayoutData->preferred = preferred; + + BAlignment childAlignment = child->LayoutAlignment(); + if (childAlignment.horizontal == B_ALIGN_USE_FULL_WIDTH) + alignment.horizontal = B_ALIGN_USE_FULL_WIDTH; + if (childAlignment.vertical == B_ALIGN_USE_FULL_HEIGHT) + alignment.vertical = B_ALIGN_USE_FULL_HEIGHT; + + fLayoutData->alignment = alignment; } else { fLayoutData->min.Set(minWidth, addHeight - 1); fLayoutData->max.Set(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED); fLayoutData->preferred = fLayoutData->min; + fLayoutData->alignment = alignment; } fLayoutData->valid = true; diff --git a/src/kits/interface/CheckBox.cpp b/src/kits/interface/CheckBox.cpp index cde4220fbd..ffe9ee3ef3 100644 --- a/src/kits/interface/CheckBox.cpp +++ b/src/kits/interface/CheckBox.cpp @@ -366,7 +366,7 @@ BCheckBox::MouseDown(BPoint point) Invalidate(); Window()->UpdateIfNeeded(); } - } + } } @@ -452,7 +452,7 @@ BSize BCheckBox::MaxSize() { return BLayoutUtils::ComposeSize(ExplicitMaxSize(), - BSize(B_SIZE_UNLIMITED, _ValidatePreferredSize().height)); + _ValidatePreferredSize()); } @@ -464,6 +464,14 @@ BCheckBox::PreferredSize() } +BAlignment +BCheckBox::LayoutAlignment() +{ + return BLayoutUtils::ComposeAlignment(ExplicitAlignment(), + BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_UNSET)); +} + + // #pragma mark - @@ -631,6 +639,6 @@ B_IF_GCC_2(InvalidateLayout__9BCheckBoxb, _ZN9BCheckBox16InvalidateLayoutEb)( perform_data_layout_invalidated data; data.descendants = descendants; - box->Perform(PERFORM_CODE_LAYOUT_INVALIDATED, &data); + box->Perform(PERFORM_CODE_LAYOUT_INVALIDATED, &data); } diff --git a/src/kits/interface/ColorControl.cpp b/src/kits/interface/ColorControl.cpp index 4187652d58..3ac5d50d7c 100644 --- a/src/kits/interface/ColorControl.cpp +++ b/src/kits/interface/ColorControl.cpp @@ -1,12 +1,13 @@ /* - * Copyright 2001-2008, Haiku Inc. + * Copyright 2001-2013 Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: - * Marc Flerackers (mflerackers@androme.be) - * Axel Dörfler, axeld@pinc-software.de * Alexandre Deckner, alex@zappotek.com + * Axel Dörfler, axeld@pinc-software.de * Jérôme Duval + * Marc Flerackers, mflerackers@androme.be + * John Scipione, jscipione@gmail.com */ /** BColorControl displays a palette of selectable colors. */ @@ -35,24 +36,29 @@ using BPrivate::gSystemCatalog; #define B_TRANSLATION_CONTEXT "ColorControl" static const uint32 kMsgColorEntered = 'ccol'; -static const uint32 kMinCellSize = 6; +static const float kMinCellSize = 6.0f; static const float kSelectorPenSize = 2.0f; static const float kSelectorSize = 4.0f; static const float kSelectorHSpacing = 2.0f; static const float kTextFieldsHSpacing = 6.0f; +static const float kDefaultFontSize = 12.0f; +static const float kBevelSpacing = 2.0f; +static const uint32 kRampCount = 4; + BColorControl::BColorControl(BPoint leftTop, color_control_layout layout, - float cellSize, const char *name, BMessage *message, - bool bufferedDrawing) - : BControl(BRect(leftTop, leftTop), name, NULL, message, - B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE) + float cellSize, const char* name, BMessage* message, bool bufferedDrawing) + : + BControl(BRect(leftTop, leftTop), name, NULL, message, + B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE) { _InitData(layout, cellSize, bufferedDrawing, NULL); } BColorControl::BColorControl(BMessage* archive) - : BControl(archive) + : + BControl(archive) { int32 layout; float cellSize; @@ -81,7 +87,8 @@ BColorControl::_InitData(color_control_layout layout, float size, // so we take the main_screen colorspace at startup fColumns = layout; fRows = 256 / fColumns; - fCellSize = ceil(max_c(kMinCellSize, size)); + + _SetCellSize(size); fSelectedPaletteColorIndex = -1; fPreviousSelectedPaletteColorIndex = -1; @@ -94,7 +101,7 @@ BColorControl::_InitData(color_control_layout layout, float size, green = gSystemCatalog.GetString(green, "ColorControl"); blue = gSystemCatalog.GetString(blue, "ColorControl"); - if (archive) { + if (archive != NULL) { fRedText = (BTextControl*)FindView("_red"); fGreenText = (BTextControl*)FindView("_green"); fBlueText = (BTextControl*)FindView("_blue"); @@ -104,20 +111,24 @@ BColorControl::_InitData(color_control_layout layout, float size, SetValue(value); } else { - BRect rect(0.0f, 0.0f, 70.0f, 15.0f); + BRect textRect(0.0f, 0.0f, 0.0f, 0.0f); float labelWidth = std::max(StringWidth(red), - std::max(StringWidth(green), StringWidth(blue))) + 5; - rect.right = labelWidth + StringWidth("999") + 20; + std::max(StringWidth(green), StringWidth(blue))) + + kTextFieldsHSpacing; + textRect.right = labelWidth + StringWidth("999999"); + // enough room for 3 digits plus 3 digits of padding + font_height fontHeight; + GetFontHeight(&fontHeight); + float labelHeight = fontHeight.ascent + fontHeight.descent; + textRect.bottom = labelHeight; // red - fRedText = new BTextControl(rect, "_red", red, "0", + fRedText = new BTextControl(textRect, "_red", red, "0", new BMessage(kMsgColorEntered), B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE); fRedText->SetDivider(labelWidth); - float offset = fRedText->Bounds().Height() + 2; - for (int32 i = 0; i < 256; i++) fRedText->TextView()->DisallowChar(i); for (int32 i = '0'; i <= '9'; i++) @@ -126,8 +137,8 @@ BColorControl::_InitData(color_control_layout layout, float size, // green - rect.OffsetBy(0.0f, offset); - fGreenText = new BTextControl(rect, "_green", green, "0", + textRect.OffsetBy(0, _TextRectOffset()); + fGreenText = new BTextControl(textRect, "_green", green, "0", new BMessage(kMsgColorEntered), B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE); fGreenText->SetDivider(labelWidth); @@ -140,8 +151,8 @@ BColorControl::_InitData(color_control_layout layout, float size, // blue - rect.OffsetBy(0.0f, offset); - fBlueText = new BTextControl(rect, "_blue", blue, "0", + textRect.OffsetBy(0, _TextRectOffset()); + fBlueText = new BTextControl(textRect, "_blue", blue, "0", new BMessage(kMsgColorEntered), B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE); fBlueText->SetDivider(labelWidth); @@ -157,12 +168,10 @@ BColorControl::_InitData(color_control_layout layout, float size, AddChild(fBlueText); } - _LayoutView(); + ResizeToPreferred(); if (useOffscreen) { - BRect bounds = fPaletteFrame; - bounds.InsetBy(-2.0f, -2.0f); - + BRect bounds = _PaletteFrame(); fBitmap = new BBitmap(bounds, B_RGB32, true, false); fOffscreenView = new BView(bounds, "off_view", 0, 0); @@ -179,32 +188,25 @@ BColorControl::_InitData(color_control_layout layout, float size, void BColorControl::_LayoutView() { - if (fPaletteMode){ - fPaletteFrame.Set(2.0f, 2.0f, - float(fColumns) * fCellSize + 2.0, - float(fRows) * fCellSize + 2.0); - } else { - fPaletteFrame.Set(2.0f, 2.0f, - float(fColumns) * fCellSize + 2.0, - float(fRows) * fCellSize + 2.0 - 1.0); - //1 pixel adjust so that the inner space - //has exactly rows*cellsize pixels in height + fPaletteFrame.Set(0, 0, fColumns * fCellSize, fRows * fCellSize); + fPaletteFrame.OffsetBy(kBevelSpacing, kBevelSpacing); + if (!fPaletteMode) { + // Reduce the inner space by 1 pixel so that the frame + // is exactly rows * cellsize pixels in height + fPaletteFrame.bottom -= 1; } - BRect rect = fPaletteFrame.InsetByCopy(-2.0,-2.0); //bevel - - if (rect.Height() < fBlueText->Frame().bottom) { - // adjust the height to fit - rect.bottom = fBlueText->Frame().bottom; - } - - float offset = floor(rect.bottom / 4); - float y = offset; - if (offset < fRedText->Bounds().Height() + 2) { - offset = fRedText->Bounds().Height() + 2; - y = 0; + float rampHeight = (float)(fRows * fCellSize / kRampCount); + float offset = _TextRectOffset(); + float y = 0; + if (rampHeight > fRedText->Frame().Height()) { + // there is enough room to fit kRampCount labels, + // shift text controls down by one ramp + offset = rampHeight; + y = floorf(offset + (offset - fRedText->Frame().Height()) / 2); } + BRect rect = _PaletteFrame(); fRedText->MoveTo(rect.right + kTextFieldsHSpacing, y); y += offset; @@ -212,14 +214,11 @@ BColorControl::_LayoutView() y += offset; fBlueText->MoveTo(rect.right + kTextFieldsHSpacing, y); - - ResizeTo(rect.Width() + kTextFieldsHSpacing + fRedText->Bounds().Width(), rect.Height()); - } -BArchivable * -BColorControl::Instantiate(BMessage *archive) +BArchivable* +BColorControl::Instantiate(BMessage* archive) { if (validate_instantiation(archive, "BColorControl")) return new BColorControl(archive); @@ -229,7 +228,7 @@ BColorControl::Instantiate(BMessage *archive) status_t -BColorControl::Archive(BMessage *archive, bool deep) const +BColorControl::Archive(BMessage* archive, bool deep) const { status_t status = BControl::Archive(archive, deep); @@ -376,7 +375,7 @@ BColorControl::AttachedToWindow() void -BColorControl::MessageReceived(BMessage *message) +BColorControl::MessageReceived(BMessage* message) { switch (message->what) { case kMsgColorEntered: @@ -400,18 +399,19 @@ BColorControl::MessageReceived(BMessage *message) void BColorControl::Draw(BRect updateRect) { - if (fBitmap) + if (fBitmap != NULL) DrawBitmap(fBitmap, B_ORIGIN); else _DrawColorArea(this, updateRect); + _DrawSelectors(this); } void -BColorControl::_DrawColorArea(BView* target, BRect update) +BColorControl::_DrawColorArea(BView* target, BRect updateRect) { - BRect bevelRect = fPaletteFrame.InsetByCopy(-2.0,-2.0); //bevel + BRect rect = _PaletteFrame(); bool enabled = IsEnabled(); rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR); @@ -421,67 +421,76 @@ BColorControl::_DrawColorArea(BView* target, BRect update) uint32 flags = 0; if (!enabled) flags |= BControlLook::B_DISABLED; - be_control_look->DrawTextControlBorder(target, bevelRect, update, - noTint, flags); + + be_control_look->DrawTextControlBorder(target, rect, updateRect, noTint, + flags); } else { rgb_color lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT); rgb_color lightenmax = tint_color(noTint, B_LIGHTEN_MAX_TINT); rgb_color darken2 = tint_color(noTint, B_DARKEN_2_TINT); rgb_color darken4 = tint_color(noTint, B_DARKEN_4_TINT); - // First bevel + // first bevel if (enabled) target->SetHighColor(darken1); else target->SetHighColor(noTint); - target->StrokeLine(bevelRect.LeftBottom(), bevelRect.LeftTop()); - target->StrokeLine(bevelRect.LeftTop(), bevelRect.RightTop()); + + target->StrokeLine(rect.LeftBottom(), rect.LeftTop()); + target->StrokeLine(rect.LeftTop(), rect.RightTop()); if (enabled) target->SetHighColor(lightenmax); else target->SetHighColor(lighten1); - target->StrokeLine(BPoint(bevelRect.left + 1.0f, bevelRect.bottom), - bevelRect.RightBottom()); - target->StrokeLine(bevelRect.RightBottom(), - BPoint(bevelRect.right, bevelRect.top + 1.0f)); - bevelRect.InsetBy(1.0f, 1.0f); + target->StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), + rect.RightBottom()); + target->StrokeLine(rect.RightBottom(), + BPoint(rect.right, rect.top + 1.0f)); - // Second bevel + rect.InsetBy(1.0f, 1.0f); + + // second bevel if (enabled) target->SetHighColor(darken4); else target->SetHighColor(darken2); - target->StrokeLine(bevelRect.LeftBottom(), bevelRect.LeftTop()); - target->StrokeLine(bevelRect.LeftTop(), bevelRect.RightTop()); + + target->StrokeLine(rect.LeftBottom(), rect.LeftTop()); + target->StrokeLine(rect.LeftTop(), rect.RightTop()); target->SetHighColor(noTint); - target->StrokeLine(BPoint(bevelRect.left + 1.0f, bevelRect.bottom), - bevelRect.RightBottom()); - target->StrokeLine(bevelRect.RightBottom(), - BPoint(bevelRect.right, bevelRect.top + 1.0f)); + target->StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), + rect.RightBottom()); + target->StrokeLine(rect.RightBottom(), + BPoint(rect.right, rect.top + 1.0f)); } if (fPaletteMode) { - int colBegin = max_c(0, -1 + int(update.left) / int(fCellSize)); - int colEnd = min_c(fColumns, 2 + int(update.right) / int(fCellSize)); - int rowBegin = max_c(0, -1 + int(update.top) / int(fCellSize)); - int rowEnd = min_c(fRows, 2 + int(update.bottom) / int(fCellSize)); + int colBegin = max_c(0, -1 + int(updateRect.left) / int(fCellSize)); + int colEnd = min_c(fColumns, + 2 + int(updateRect.right) / int(fCellSize)); + int rowBegin = max_c(0, -1 + int(updateRect.top) / int(fCellSize)); + int rowEnd = min_c(fRows, 2 + int(updateRect.bottom) + / int(fCellSize)); - //grid + // grid if (enabled) target->SetHighColor(darken1); else target->SetHighColor(noTint); - for (int xi = 0; xi < fColumns+1; xi++) { + + for (int xi = 0; xi < fColumns + 1; xi++) { float x = fPaletteFrame.left + float(xi) * fCellSize; - target->StrokeLine(BPoint(x, fPaletteFrame.top), BPoint(x, fPaletteFrame.bottom)); + target->StrokeLine(BPoint(x, fPaletteFrame.top), + BPoint(x, fPaletteFrame.bottom)); } - for (int yi = 0; yi < fRows+1; yi++) { + for (int yi = 0; yi < fRows + 1; yi++) { float y = fPaletteFrame.top + float(yi) * fCellSize; - target->StrokeLine(BPoint(fPaletteFrame.left, y), BPoint(fPaletteFrame.right, y)); + target->StrokeLine(BPoint(fPaletteFrame.left, y), + BPoint(fPaletteFrame.right, y)); } - //colors + // colors for (int col = colBegin; col < colEnd; col++) { for (int row = rowBegin; row < rowEnd; row++) { uint8 colorIndex = row * fColumns + col; @@ -489,25 +498,30 @@ BColorControl::_DrawColorArea(BView* target, BRect update) float y = fPaletteFrame.top + row * fCellSize; target->SetHighColor(system_colors()->color_list[colorIndex]); - target->FillRect(BRect(x+1, y+1, x + fCellSize - 1, y + fCellSize - 1)); + target->FillRect(BRect(x + 1, y + 1, + x + fCellSize - 1, y + fCellSize - 1)); } } } else { - rgb_color white = {255, 255, 255, 255}; - rgb_color red = {255, 0, 0, 255}; - rgb_color green = {0, 255, 0, 255}; - rgb_color blue = {0, 0, 255, 255}; + rgb_color white = { 255, 255, 255, 255 }; + rgb_color red = { 255, 0, 0, 255 }; + rgb_color green = { 0, 255, 0, 255 }; + rgb_color blue = { 0, 0, 255, 255 }; - rgb_color compColor = {0, 0, 0, 255}; + rgb_color compColor = { 0, 0, 0, 255 }; if (!enabled) { compColor.red = compColor.green = compColor.blue = 156; red.red = green.green = blue.blue = 70; white.red = white.green = white.blue = 70; } - _ColorRamp(_RampFrame(0), target, white, compColor, 0, false, update); - _ColorRamp(_RampFrame(1), target, red, compColor, 0, false, update); - _ColorRamp(_RampFrame(2), target, green, compColor, 0, false, update); - _ColorRamp(_RampFrame(3), target, blue, compColor, 0, false, update); + _DrawColorRamp(_RampFrame(0), target, white, compColor, 0, false, + updateRect); + _DrawColorRamp(_RampFrame(1), target, red, compColor, 0, false, + updateRect); + _DrawColorRamp(_RampFrame(2), target, green, compColor, 0, false, + updateRect); + _DrawColorRamp(_RampFrame(3), target, blue, compColor, 0, false, + updateRect); } } @@ -520,7 +534,7 @@ BColorControl::_DrawSelectors(BView* target) if (fPaletteMode) { if (fSelectedPaletteColorIndex != -1) { - target->SetHighColor(lightenmax); + target->SetHighColor(lightenmax); target->StrokeRect(_PaletteSelectorFrame(fSelectedPaletteColorIndex)); } } else { @@ -541,21 +555,24 @@ BColorControl::_DrawSelectors(BView* target) void -BColorControl::_ColorRamp(BRect rect, BView* target, - rgb_color baseColor, rgb_color compColor, int16 flag, bool focused, BRect update) +BColorControl::_DrawColorRamp(BRect rect, BView* target, + rgb_color baseColor, rgb_color compColor, int16 flag, bool focused, + BRect updateRect) { float width = rect.Width() + 1; rgb_color color; color.alpha = 255; - update = update & rect; + updateRect = updateRect & rect; - if (update.IsValid() && update.Width() >= 0){ - target->BeginLineArray((int32)update.Width() + 1); + if (updateRect.IsValid() && updateRect.Width() >= 0) { + target->BeginLineArray((int32)updateRect.Width() + 1); - for (float i = (update.left - rect.left); i <= (update.right - rect.left) + 1; i++) { + for (float i = (updateRect.left - rect.left); + i <= (updateRect.right - rect.left) + 1; i++) { color.red = (uint8)(i * baseColor.red / width) + compColor.red; - color.green = (uint8)(i * baseColor.green / width) + compColor.green; + color.green = (uint8)(i * baseColor.green / width) + + compColor.green; color.blue = (uint8)(i * baseColor.blue / width) + compColor.blue; target->AddLine(BPoint(rect.left + i, rect.top), BPoint(rect.left + i, rect.bottom - 1), color); @@ -577,18 +594,43 @@ BColorControl::_SelectorPosition(const BRect& rampRect, uint8 shade) const } +BRect +BColorControl::_PaletteFrame() const +{ + return fPaletteFrame.InsetByCopy(-kBevelSpacing, -kBevelSpacing); +} + + BRect BColorControl::_RampFrame(uint8 rampIndex) const { - float rampHeight = float(fRows) * fCellSize / 4.0f; + float rampHeight = (float)(fRows * fCellSize / kRampCount); - return BRect( fPaletteFrame.left, + return BRect(fPaletteFrame.left, fPaletteFrame.top + float(rampIndex) * rampHeight, fPaletteFrame.right, fPaletteFrame.top + float(rampIndex + 1) * rampHeight); } +void +BColorControl::_SetCellSize(float size) +{ + BFont font; + GetFont(&font); + fCellSize = std::max(kMinCellSize, + ceilf(size * font.Size() / kDefaultFontSize)); +} + + +float +BColorControl::_TextRectOffset() +{ + return std::max(fRedText->Bounds().Height(), + ceilf(_PaletteFrame().Height() / 3)); +} + + BRect BColorControl::_PaletteSelectorFrame(uint8 colorIndex) const { @@ -604,7 +646,7 @@ void BColorControl::_InitOffscreen() { if (fBitmap->Lock()) { - _DrawColorArea(fOffscreenView, fPaletteFrame.InsetByCopy(-2.0f,-2.0f)); + _DrawColorArea(fOffscreenView, _PaletteFrame()); fOffscreenView->Sync(); fBitmap->Unlock(); } @@ -612,10 +654,9 @@ BColorControl::_InitOffscreen() void -BColorControl::SetCellSize(float cellSide) +BColorControl::SetCellSize(float size) { - fCellSize = ceil(max_c(kMinCellSize, cellSide)); - _LayoutView(); + _SetCellSize(size); ResizeToPreferred(); } @@ -653,8 +694,6 @@ BColorControl::SetLayout(color_control_layout layout) break; } - _LayoutView(); - ResizeToPreferred(); Invalidate(); } @@ -712,9 +751,9 @@ BColorControl::MouseDown(BPoint point) MakeFocus(); if (fPaletteMode) { - int column = (int) ( (point.x - fPaletteFrame.left) / fCellSize ); - int row = (int) ( (point.y - fPaletteFrame.top) / fCellSize ); - int colorIndex = row * fColumns + column; + int col = (int)((point.x - fPaletteFrame.left) / fCellSize); + int row = (int)((point.y - fPaletteFrame.top) / fCellSize); + int colorIndex = row * fColumns + col; if (colorIndex >= 0 && colorIndex < 256) { fSelectedPaletteColorIndex = colorIndex; SetValue(system_colors()->color_list[colorIndex]); @@ -723,8 +762,8 @@ BColorControl::MouseDown(BPoint point) rgb_color color = ValueAsColor(); uint8 shade = (unsigned char)max_c(0, - min_c((point.x - _RampFrame(0).left) * 255 / _RampFrame(0).Width(), - 255)); + min_c((point.x - _RampFrame(0).left) * 255 + / _RampFrame(0).Width(), 255)); if (_RampFrame(0).Contains(point)) { color.red = color.green = color.blue = shade; @@ -741,27 +780,27 @@ BColorControl::MouseDown(BPoint point) } SetValue(color); - } Invoke(); SetTracking(true); - SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY|B_LOCK_WINDOW_FOCUS); + SetMouseEventMask(B_POINTER_EVENTS, + B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS); } void BColorControl::MouseMoved(BPoint point, uint32 transit, - const BMessage *message) + const BMessage* message) { if (!IsTracking()) return; if (fPaletteMode && fPaletteFrame.Contains(point)) { - int column = (int) ( (point.x - fPaletteFrame.left) / fCellSize ); - int row = (int) ( (point.y - fPaletteFrame.top) / fCellSize ); - int colorIndex = row * fColumns + column; + int col = (int)((point.x - fPaletteFrame.left) / fCellSize); + int row = (int)((point.y - fPaletteFrame.top) / fCellSize); + int colorIndex = row * fColumns + col; if (colorIndex >= 0 && colorIndex < 256) { fSelectedPaletteColorIndex = colorIndex; SetValue(system_colors()->color_list[colorIndex]); @@ -773,7 +812,8 @@ BColorControl::MouseMoved(BPoint point, uint32 transit, rgb_color color = ValueAsColor(); uint8 shade = (unsigned char)max_c(0, - min_c((point.x - _RampFrame(0).left) * 255 / _RampFrame(0).Width(), 255)); + min_c((point.x - _RampFrame(0).left) * 255 + / _RampFrame(0).Width(), 255)); switch (fFocusedComponent) { case 1: @@ -807,17 +847,19 @@ BColorControl::DetachedFromWindow() void -BColorControl::GetPreferredSize(float *_width, float *_height) +BColorControl::GetPreferredSize(float* _width, float* _height) { - BRect rect = fPaletteFrame.InsetByCopy(-2.0,-2.0); //bevel + BRect rect = _PaletteFrame(); if (rect.Height() < fBlueText->Frame().bottom) { // adjust the height to fit rect.bottom = fBlueText->Frame().bottom; } - if (_width) - *_width = rect.Width() + kTextFieldsHSpacing + fRedText->Bounds().Width(); + if (_width) { + *_width = rect.Width() + kTextFieldsHSpacing + + fRedText->Bounds().Width(); + } if (_height) *_height = rect.Height(); @@ -827,16 +869,15 @@ BColorControl::GetPreferredSize(float *_width, float *_height) void BColorControl::ResizeToPreferred() { - BControl::ResizeToPreferred(); - _LayoutView(); + BControl::ResizeToPreferred(); } status_t -BColorControl::Invoke(BMessage *msg) +BColorControl::Invoke(BMessage* message) { - return BControl::Invoke(msg); + return BControl::Invoke(message); } @@ -854,16 +895,17 @@ BColorControl::FrameResized(float new_width, float new_height) } -BHandler * -BColorControl::ResolveSpecifier(BMessage *msg, int32 index, - BMessage *specifier, int32 form, const char *property) +BHandler* +BColorControl::ResolveSpecifier(BMessage* message, int32 index, + BMessage* specifier, int32 form, const char* property) { - return BControl::ResolveSpecifier(msg, index, specifier, form, property); + return BControl::ResolveSpecifier(message, index, specifier, form, + property); } status_t -BColorControl::GetSupportedSuites(BMessage *data) +BColorControl::GetSupportedSuites(BMessage* data) { return BControl::GetSupportedSuites(data); } @@ -918,10 +960,10 @@ BColorControl::Perform(perform_code code, void* _data) { perform_data_get_height_for_width* data = (perform_data_get_height_for_width*)_data; - BColorControl::GetHeightForWidth(data->width, &data->min, &data->max, - &data->preferred); + BColorControl::GetHeightForWidth(data->width, &data->min, + &data->max, &data->preferred); return B_OK; -} + } case PERFORM_CODE_SET_LAYOUT: { perform_data_set_layout* data = (perform_data_set_layout*)_data; diff --git a/src/kits/interface/ColumnListView.cpp b/src/kits/interface/ColumnListView.cpp index ec8b1affa7..f9b67a0739 100644 --- a/src/kits/interface/ColumnListView.cpp +++ b/src/kits/interface/ColumnListView.cpp @@ -3070,9 +3070,9 @@ OutlineView::Clear() DeselectAll(); // Make sure selection list doesn't point to deleted rows! RecursiveDeleteRows(&fRows, false); - Invalidate(); fItemsHeight = 0.0; FixScrollBar(true); + Invalidate(); } @@ -4378,7 +4378,7 @@ OutlineView::FixScrollBar(bool scrollToFit) vScrollBar->SetRange(0.0, maxScrollBarValue); vScrollBar->SetSteps(20.0, fVisibleRect.Height()); } - } else if (vScrollBar->Value() == 0.0) + } else if (vScrollBar->Value() == 0.0 || fItemsHeight == 0.0) vScrollBar->SetRange(0.0, 0.0); // disable scroll bar. } } diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 3b7bb02108..737424531e 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -2085,7 +2085,8 @@ BMenu::_LayoutItems(int32 index) { _CalcTriggers(); - float width, height; + float width; + float height; _ComputeLayout(index, fResizeToFit, true, &width, &height); if (fResizeToFit) @@ -2128,8 +2129,7 @@ BMenu::_ComputeLayout(int32 index, bool bestFit, bool moveItems, overrideFrame = &parentFrame; } - _ComputeColumnLayout(index, bestFit, moveItems, overrideFrame, - frame); + _ComputeColumnLayout(index, bestFit, moveItems, overrideFrame, frame); break; } case B_ITEMS_IN_ROW: @@ -2147,9 +2147,11 @@ BMenu::_ComputeLayout(int32 index, bool bestFit, bool moveItems, // change width depending on resize mode BSize size; if ((ResizingMode() & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT) { - if (Parent()) + if (dynamic_cast<_BMCMenuBar_*>(this) != NULL) + size.width = Bounds().Width() - fPad.right; + else if (Parent() != NULL) size.width = Parent()->Frame().Width() + 1; - else if (Window()) + else if (Window() != NULL) size.width = Window()->Frame().Width() + 1; else size.width = Bounds().Width(); diff --git a/src/kits/interface/MenuField.cpp b/src/kits/interface/MenuField.cpp index cdfe7477f7..f660b9e38c 100644 --- a/src/kits/interface/MenuField.cpp +++ b/src/kits/interface/MenuField.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -131,7 +132,8 @@ struct BMenuField::LayoutData { // #pragma mark - -static float kVMargin = 2.0f; +static const float kMinMenuBarWidth = 20.0f; + // found by experimenting on BeOS R5 BMenuField::BMenuField(BRect frame, const char* name, const char* label, @@ -400,8 +402,18 @@ BMenuField::AllAttached() TRACE("width: %.2f, height: %.2f\n", Frame().Width(), Frame().Height()); - ResizeTo(Bounds().Width(), - fMenuBar->Bounds().Height() + kVMargin + kVMargin); + float width = Bounds().Width(); + if (!fFixedSizeMB && _MenuBarWidth() < kMinMenuBarWidth) { + // The menu bar is too narrow, resize it to fit the menu items + BMenuItem* item = fMenuBar->ItemAt(0); + if (item != NULL) { + float right; + fMenuBar->GetItemMargins(NULL, NULL, &right, NULL); + width = item->Frame().Width() + kVMargin + _MenuBarOffset() + right; + } + } + + ResizeTo(width, fMenuBar->Bounds().Height() + kVMargin * 2); TRACE("width: %.2f, height: %.2f\n", Frame().Width(), Frame().Height()); } @@ -527,6 +539,16 @@ BMenuField::FrameResized(float newWidth, float newHeight) { BView::FrameResized(newWidth, newHeight); + if (fFixedSizeMB) { + // we have let the menubar resize itself, but + // in fixed size mode, the menubar is supposed to + // be at the right end of the view always. Since + // the menu bar is in follow left/right mode then, + // resizing ourselfs might have caused the menubar + // to be outside now + fMenuBar->ResizeTo(_MenuBarWidth(), fMenuBar->Frame().Height()); + } + if (newHeight != fLayoutData->previous_height && Label()) { // The height changed, which means the label has to move and we // probably also invalidate a part of the borders around the menu bar. @@ -625,10 +647,9 @@ BMenuField::Alignment() const void BMenuField::SetDivider(float position) { - position = floorf(position + 0.5); + position = roundf(position); float delta = fDivider - position; - if (delta == 0.0f) return; @@ -711,15 +732,7 @@ BMenuField::ResizeToPreferred() BView::ResizeToPreferred(); - if (fFixedSizeMB) { - // we have let the menubar resize itself, but - // in fixed size mode, the menubar is supposed to - // be at the right end of the view always. Since - // the menu bar is in follow left/right mode then, - // resizing ourselfs might have caused the menubar - // to be outside now - fMenuBar->ResizeTo(_MenuBarWidth(), fMenuBar->Frame().Height()); - } + Invalidate(); } @@ -964,9 +977,11 @@ BMenuField::InitObject2() { CALLED(); - float height; - fMenuBar->GetPreferredSize(NULL, &height); - fMenuBar->ResizeTo(_MenuBarWidth(), height); + if (!fFixedSizeMB) { + float height; + fMenuBar->GetPreferredSize(NULL, &height); + fMenuBar->ResizeTo(_MenuBarWidth(), height); + } TRACE("frame(%.1f, %.1f, %.1f, %.1f) (%.2f, %.2f)\n", fMenuBar->Frame().left, fMenuBar->Frame().top, diff --git a/src/kits/interface/MenuItem.cpp b/src/kits/interface/MenuItem.cpp index 4e5691b2ab..60e9abd924 100644 --- a/src/kits/interface/MenuItem.cpp +++ b/src/kits/interface/MenuItem.cpp @@ -406,7 +406,9 @@ BMenuItem::DrawContent() GetContentSize(&labelWidth, &labelHeight); const BRect& padding = menuPrivate.Padding(); - float frameWidth = fSuper->Frame().Width() - padding.left - padding.right; + float maxContentWidth = fSuper->MaxContentWidth(); + float frameWidth = maxContentWidth > 0 ? maxContentWidth + : fSuper->Frame().Width() - padding.left - padding.right; if (roundf(frameWidth) >= roundf(labelWidth)) fSuper->DrawString(fLabel); diff --git a/src/kits/interface/RadioButton.cpp b/src/kits/interface/RadioButton.cpp index e3b3cfbee4..3e7659d0eb 100644 --- a/src/kits/interface/RadioButton.cpp +++ b/src/kits/interface/RadioButton.cpp @@ -566,10 +566,17 @@ BRadioButton::MaxSize() GetPreferredSize(&width, &height); return BLayoutUtils::ComposeSize(ExplicitMaxSize(), - BSize(B_SIZE_UNLIMITED, height)); + BSize(width, height)); } +BAlignment +BRadioButton::LayoutAlignment() +{ + return BLayoutUtils::ComposeAlignment(ExplicitAlignment(), + BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_UNSET)); +} + void BRadioButton::_ReservedRadioButton1() {} diff --git a/src/kits/interface/StringView.cpp b/src/kits/interface/StringView.cpp index 8c6981ebc4..67991fbc56 100644 --- a/src/kits/interface/StringView.cpp +++ b/src/kits/interface/StringView.cpp @@ -19,12 +19,32 @@ #include #include +#include #include #include #include +static property_info sPropertyList[] = { + { + "Text", + { B_GET_PROPERTY, B_SET_PROPERTY }, + { B_DIRECT_SPECIFIER }, + NULL, 0, + { B_STRING_TYPE } + }, + { + "Alignment", + { B_GET_PROPERTY, B_SET_PROPERTY }, + { B_DIRECT_SPECIFIER }, + NULL, 0, + { B_INT32_TYPE } + }, + {} +}; + + BStringView::BStringView(BRect frame, const char* name, const char* text, uint32 resizeMask, uint32 flags) : BView(frame, name, resizeMask, flags | B_FULL_UPDATE_ON_RESIZE), @@ -261,6 +281,51 @@ BStringView::Draw(BRect updateRect) void BStringView::MessageReceived(BMessage* message) { + if (message->what == B_GET_PROPERTY || message->what == B_SET_PROPERTY) { + int32 index; + BMessage specifier; + int32 form; + const char* property; + if (message->GetCurrentSpecifier(&index, &specifier, &form, &property) + != B_OK) { + BView::MessageReceived(message); + return; + } + + BMessage reply(B_REPLY); + bool handled = false; + if (strcmp(property, "Text") == 0) { + if (message->what == B_GET_PROPERTY) { + reply.AddString("result", fText); + handled = true; + } else { + const char* text; + if (message->FindString("data", &text) == B_OK) { + SetText(text); + reply.AddInt32("error", B_OK); + handled = true; + } + } + } else if (strcmp(property, "Alignment") == 0) { + if (message->what == B_GET_PROPERTY) { + reply.AddInt32("result", (int32)fAlign); + handled = true; + } else { + int32 align; + if (message->FindInt32("data", &align) == B_OK) { + SetAlignment((alignment)align); + reply.AddInt32("error", B_OK); + handled = true; + } + } + } + + if (handled) { + message->SendReply(&reply); + return; + } + } + BView::MessageReceived(message); } @@ -331,17 +396,33 @@ BStringView::Alignment() const BHandler* -BStringView::ResolveSpecifier(BMessage* msg, int32 index, +BStringView::ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier, int32 form, const char* property) { - return NULL; + BPropertyInfo propInfo(sPropertyList); + if (propInfo.FindMatch(message, 0, specifier, form, property) >= B_OK) + return this; + + return BView::ResolveSpecifier(message, index, specifier, form, property); } status_t -BStringView::GetSupportedSuites(BMessage* message) +BStringView::GetSupportedSuites(BMessage* data) { - return BView::GetSupportedSuites(message); + if (data == NULL) + return B_BAD_VALUE; + + status_t status = data->AddString("suites", "suite/vnd.Be-string-view"); + if (status != B_OK) + return status; + + BPropertyInfo propertyInfo(sPropertyList); + status = data->AddFlat("messages", &propertyInfo); + if (status != B_OK) + return status; + + return BView::GetSupportedSuites(data); } diff --git a/src/kits/interface/TabView.cpp b/src/kits/interface/TabView.cpp index 1b06aa05f5..452314c8c9 100644 --- a/src/kits/interface/TabView.cpp +++ b/src/kits/interface/TabView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009, Haiku, Inc. All rights reserved. + * Copyright 2001-2013, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -7,6 +7,7 @@ * Jérôme Duval (korli@users.berlios.de) * Stephan Aßmus * Artur Wyszynski + * Rene Gollent (rene@gollent.com) */ @@ -429,7 +430,7 @@ BTabView::BTabView(BMessage *archive) } if (archive->FindInt32("_sel", &fSelection) != B_OK) - fSelection = 0; + fSelection = -1; if (archive->FindInt32("_border_style", (int32*)&fBorderStyle) != B_OK) fBorderStyle = B_FANCY_BORDER; @@ -568,7 +569,8 @@ BTabView::AttachedToWindow() { BView::AttachedToWindow(); - Select(fSelection); + if (fSelection < 0) + Select(0); } @@ -746,6 +748,9 @@ BTabView::Pulse() void BTabView::Select(int32 index) { + if (index == Selection()) + return; + if (index < 0 || index >= CountTabs()) index = Selection(); @@ -1238,13 +1243,10 @@ BTabView::RemoveTab(int32 index) if (fContainerView->GetLayout()) fContainerView->GetLayout()->RemoveItem(index); - if (index <= fSelection && fSelection != 0) - fSelection--; - if (CountTabs() == 0) fFocus = -1; - else - Select(fSelection); + else if (index <= fSelection) + Select(fSelection - 1); if (fFocus == CountTabs() - 1 || CountTabs() == 0) SetFocusTab(fFocus, false); @@ -1351,7 +1353,7 @@ BTabView::_InitObject(bool layouted, button_width width) fTabList = new BList; fTabWidthSetting = width; - fSelection = 0; + fSelection = -1; fFocus = -1; fTabOffset = 0.0f; fBorderStyle = B_FANCY_BORDER; diff --git a/src/kits/interface/TextControl.cpp b/src/kits/interface/TextControl.cpp index 90ee19dd13..05ba91b6ba 100644 --- a/src/kits/interface/TextControl.cpp +++ b/src/kits/interface/TextControl.cpp @@ -850,6 +850,17 @@ BTextControl::PreferredSize() } +BAlignment +BTextControl::LayoutAlignment() +{ + CALLED(); + + _ValidateLayoutData(); + return BLayoutUtils::ComposeAlignment(ExplicitAlignment(), + BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_UNSET)); +} + + BLayoutItem* BTextControl::CreateLabelLayoutItem() { diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index d1bc743b35..f9894fff9c 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -1,12 +1,12 @@ /* - * Copyright 2001-2012, Haiku. + * Copyright 2001-2013 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: - * Adrian Oanca + * Stephan Aßmus, superstippi@gmx.de * Axel Dörfler, axeld@pinc-software.de - * Stephan Aßmus - * Ingo Weinhold + * Adrian Oanca, adioanca@cotty.iren.ro + * Ingo Weinhold. ingo_weinhold@gmx.de */ @@ -834,11 +834,11 @@ BView::ConvertFromParent(BRect rect) const void -BView::_ConvertToScreen(BPoint* pt, bool checkLock) const +BView::_ConvertToScreen(BPoint* point, bool checkLock) const { if (!fParent) { if (fOwner) - fOwner->ConvertToScreen(pt); + fOwner->ConvertToScreen(point); return; } @@ -846,33 +846,33 @@ BView::_ConvertToScreen(BPoint* pt, bool checkLock) const if (checkLock) _CheckOwnerLock(); - _ConvertToParent(pt, false); - fParent->_ConvertToScreen(pt, false); + _ConvertToParent(point, false); + fParent->_ConvertToScreen(point, false); } void -BView::ConvertToScreen(BPoint* pt) const +BView::ConvertToScreen(BPoint* point) const { - _ConvertToScreen(pt, true); + _ConvertToScreen(point, true); } BPoint -BView::ConvertToScreen(BPoint pt) const +BView::ConvertToScreen(BPoint point) const { - ConvertToScreen(&pt); + ConvertToScreen(&point); - return pt; + return point; } void -BView::_ConvertFromScreen(BPoint* pt, bool checkLock) const +BView::_ConvertFromScreen(BPoint* point, bool checkLock) const { if (!fParent) { if (fOwner) - fOwner->ConvertFromScreen(pt); + fOwner->ConvertFromScreen(point); return; } @@ -880,24 +880,24 @@ BView::_ConvertFromScreen(BPoint* pt, bool checkLock) const if (checkLock) _CheckOwnerLock(); - _ConvertFromParent(pt, false); - fParent->_ConvertFromScreen(pt, false); + _ConvertFromParent(point, false); + fParent->_ConvertFromScreen(point, false); } void -BView::ConvertFromScreen(BPoint* pt) const +BView::ConvertFromScreen(BPoint* point) const { - _ConvertFromScreen(pt, true); + _ConvertFromScreen(point, true); } BPoint -BView::ConvertFromScreen(BPoint pt) const +BView::ConvertFromScreen(BPoint point) const { - ConvertFromScreen(&pt); + ConvertFromScreen(&point); - return pt; + return point; } @@ -2739,7 +2739,7 @@ BView::FillEllipse(BPoint center, float xRadius, float yRadius, const BGradient& gradient) { FillEllipse(BRect(center.x - xRadius, center.y - yRadius, - center.x + xRadius, center.y + yRadius), gradient); + center.x + xRadius, center.y + yRadius), gradient); } @@ -2919,7 +2919,7 @@ BView::FillBezier(BPoint* controlPoints, const BGradient& gradient) void BView::StrokePolygon(const BPolygon* polygon, bool closed, ::pattern pattern) { - if (!polygon) + if (polygon == NULL) return; StrokePolygon(polygon->fPoints, polygon->fCount, polygon->Frame(), closed, @@ -2939,10 +2939,10 @@ BView::StrokePolygon(const BPoint* pointArray, int32 numPoints, bool closed, void -BView::StrokePolygon(const BPoint* ptArray, int32 numPoints, BRect bounds, +BView::StrokePolygon(const BPoint* pointArray, int32 numPoints, BRect bounds, bool closed, ::pattern pattern) { - if (!ptArray + if (pointArray == NULL || numPoints <= 1 || fOwner == NULL) return; @@ -2950,7 +2950,7 @@ BView::StrokePolygon(const BPoint* ptArray, int32 numPoints, BRect bounds, _CheckLockAndSwitchCurrent(); _UpdatePattern(pattern); - BPolygon polygon(ptArray, numPoints); + BPolygon polygon(pointArray, numPoints); polygon.MapTo(polygon.Frame(), bounds); if (fOwner->fLink->StartMessage(AS_STROKE_POLYGON, @@ -3021,50 +3021,50 @@ BView::FillPolygon(const BPolygon* polygon, const BGradient& gradient) void -BView::FillPolygon(const BPoint* ptArray, int32 numPts, ::pattern pattern) +BView::FillPolygon(const BPoint* pointArray, int32 numPoints, ::pattern pattern) { - if (!ptArray) + if (pointArray == NULL) return; - BPolygon polygon(ptArray, numPts); + BPolygon polygon(pointArray, numPoints); FillPolygon(&polygon, pattern); } void -BView::FillPolygon(const BPoint* ptArray, int32 numPts, +BView::FillPolygon(const BPoint* pointArray, int32 numPoints, const BGradient& gradient) { - if (!ptArray) + if (pointArray == NULL) return; - BPolygon polygon(ptArray, numPts); + BPolygon polygon(pointArray, numPoints); FillPolygon(&polygon, gradient); } void -BView::FillPolygon(const BPoint* ptArray, int32 numPts, BRect bounds, - pattern p) +BView::FillPolygon(const BPoint* pointArray, int32 numPoints, BRect bounds, + ::pattern pattern) { - if (!ptArray) + if (pointArray == NULL) return; - BPolygon polygon(ptArray, numPts); + BPolygon polygon(pointArray, numPoints); polygon.MapTo(polygon.Frame(), bounds); - FillPolygon(&polygon, p); + FillPolygon(&polygon, pattern); } void -BView::FillPolygon(const BPoint* ptArray, int32 numPts, BRect bounds, +BView::FillPolygon(const BPoint* pointArray, int32 numPoints, BRect bounds, const BGradient& gradient) { - if (!ptArray) + if (pointArray == NULL) return; - BPolygon polygon(ptArray, numPts); + BPolygon polygon(pointArray, numPoints); polygon.MapTo(polygon.Frame(), bounds); FillPolygon(&polygon, gradient); @@ -3221,7 +3221,7 @@ BView::FillRegion(BRegion* region, const BGradient& gradient) void -BView::StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3, BRect bounds, +BView::StrokeTriangle(BPoint point1, BPoint point2, BPoint point3, BRect bounds, ::pattern pattern) { if (fOwner == NULL) @@ -3232,9 +3232,9 @@ BView::StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3, BRect bounds, _UpdatePattern(pattern); fOwner->fLink->StartMessage(AS_STROKE_TRIANGLE); - fOwner->fLink->Attach(pt1); - fOwner->fLink->Attach(pt2); - fOwner->fLink->Attach(pt3); + fOwner->fLink->Attach(point1); + fOwner->fLink->Attach(point2); + fOwner->fLink->Attach(point3); fOwner->fLink->Attach(bounds); _FlushIfNotInTransaction(); @@ -3242,125 +3242,127 @@ BView::StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3, BRect bounds, void -BView::StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3, pattern p) +BView::StrokeTriangle(BPoint point1, BPoint point2, BPoint point3, + ::pattern pattern) { if (fOwner) { // we construct the smallest rectangle that contains the 3 points // for the 1st point - BRect bounds(pt1, pt1); + BRect bounds(point1, point1); // for the 2nd point - if (pt2.x < bounds.left) - bounds.left = pt2.x; + if (point2.x < bounds.left) + bounds.left = point2.x; - if (pt2.y < bounds.top) - bounds.top = pt2.y; + if (point2.y < bounds.top) + bounds.top = point2.y; - if (pt2.x > bounds.right) - bounds.right = pt2.x; + if (point2.x > bounds.right) + bounds.right = point2.x; - if (pt2.y > bounds.bottom) - bounds.bottom = pt2.y; + if (point2.y > bounds.bottom) + bounds.bottom = point2.y; // for the 3rd point - if (pt3.x < bounds.left) - bounds.left = pt3.x; + if (point3.x < bounds.left) + bounds.left = point3.x; - if (pt3.y < bounds.top) - bounds.top = pt3.y; + if (point3.y < bounds.top) + bounds.top = point3.y; - if (pt3.x > bounds.right) - bounds.right = pt3.x; + if (point3.x > bounds.right) + bounds.right = point3.x; - if (pt3.y > bounds.bottom) - bounds.bottom = pt3.y; + if (point3.y > bounds.bottom) + bounds.bottom = point3.y; - StrokeTriangle(pt1, pt2, pt3, bounds, p); + StrokeTriangle(point1, point2, point3, bounds, pattern); } } void -BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, pattern p) +BView::FillTriangle(BPoint point1, BPoint point2, BPoint point3, + ::pattern pattern) { if (fOwner) { // we construct the smallest rectangle that contains the 3 points // for the 1st point - BRect bounds(pt1, pt1); + BRect bounds(point1, point1); // for the 2nd point - if (pt2.x < bounds.left) - bounds.left = pt2.x; + if (point2.x < bounds.left) + bounds.left = point2.x; - if (pt2.y < bounds.top) - bounds.top = pt2.y; + if (point2.y < bounds.top) + bounds.top = point2.y; - if (pt2.x > bounds.right) - bounds.right = pt2.x; + if (point2.x > bounds.right) + bounds.right = point2.x; - if (pt2.y > bounds.bottom) - bounds.bottom = pt2.y; + if (point2.y > bounds.bottom) + bounds.bottom = point2.y; // for the 3rd point - if (pt3.x < bounds.left) - bounds.left = pt3.x; + if (point3.x < bounds.left) + bounds.left = point3.x; - if (pt3.y < bounds.top) - bounds.top = pt3.y; + if (point3.y < bounds.top) + bounds.top = point3.y; - if (pt3.x > bounds.right) - bounds.right = pt3.x; + if (point3.x > bounds.right) + bounds.right = point3.x; - if (pt3.y > bounds.bottom) - bounds.bottom = pt3.y; + if (point3.y > bounds.bottom) + bounds.bottom = point3.y; - FillTriangle(pt1, pt2, pt3, bounds, p); + FillTriangle(point1, point2, point3, bounds, pattern); } } void -BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, +BView::FillTriangle(BPoint point1, BPoint point2, BPoint point3, const BGradient& gradient) { if (fOwner) { // we construct the smallest rectangle that contains the 3 points // for the 1st point - BRect bounds(pt1, pt1); + BRect bounds(point1, point1); // for the 2nd point - if (pt2.x < bounds.left) - bounds.left = pt2.x; + if (point2.x < bounds.left) + bounds.left = point2.x; - if (pt2.y < bounds.top) - bounds.top = pt2.y; + if (point2.y < bounds.top) + bounds.top = point2.y; - if (pt2.x > bounds.right) - bounds.right = pt2.x; + if (point2.x > bounds.right) + bounds.right = point2.x; - if (pt2.y > bounds.bottom) - bounds.bottom = pt2.y; + if (point2.y > bounds.bottom) + bounds.bottom = point2.y; // for the 3rd point - if (pt3.x < bounds.left) - bounds.left = pt3.x; + if (point3.x < bounds.left) + bounds.left = point3.x; - if (pt3.y < bounds.top) - bounds.top = pt3.y; + if (point3.y < bounds.top) + bounds.top = point3.y; - if (pt3.x > bounds.right) - bounds.right = pt3.x; + if (point3.x > bounds.right) + bounds.right = point3.x; - if (pt3.y > bounds.bottom) - bounds.bottom = pt3.y; + if (point3.y > bounds.bottom) + bounds.bottom = point3.y; - FillTriangle(pt1, pt2, pt3, bounds, gradient); + FillTriangle(point1, point2, point3, bounds, gradient); } } void -BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, +BView::FillTriangle(BPoint point1, BPoint point2, BPoint point3, BRect bounds, ::pattern pattern) { if (fOwner == NULL) @@ -3370,9 +3372,9 @@ BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, _UpdatePattern(pattern); fOwner->fLink->StartMessage(AS_FILL_TRIANGLE); - fOwner->fLink->Attach(pt1); - fOwner->fLink->Attach(pt2); - fOwner->fLink->Attach(pt3); + fOwner->fLink->Attach(point1); + fOwner->fLink->Attach(point2); + fOwner->fLink->Attach(point3); fOwner->fLink->Attach(bounds); _FlushIfNotInTransaction(); @@ -3380,17 +3382,17 @@ BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, void -BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, - BRect bounds, const BGradient& gradient) +BView::FillTriangle(BPoint point1, BPoint point2, BPoint point3, BRect bounds, + const BGradient& gradient) { if (fOwner == NULL) return; _CheckLockAndSwitchCurrent(); fOwner->fLink->StartMessage(AS_FILL_TRIANGLE_GRADIENT); - fOwner->fLink->Attach(pt1); - fOwner->fLink->Attach(pt2); - fOwner->fLink->Attach(pt3); + fOwner->fLink->Attach(point1); + fOwner->fLink->Attach(point2); + fOwner->fLink->Attach(point3); fOwner->fLink->Attach(bounds); fOwner->fLink->AttachGradient(gradient); @@ -3399,14 +3401,14 @@ BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, void -BView::StrokeLine(BPoint toPt, pattern p) +BView::StrokeLine(BPoint toPoint, ::pattern pattern) { - StrokeLine(PenLocation(), toPt, p); + StrokeLine(PenLocation(), toPoint, pattern); } void -BView::StrokeLine(BPoint pt0, BPoint pt1, ::pattern pattern) +BView::StrokeLine(BPoint start, BPoint end, ::pattern pattern) { if (fOwner == NULL) return; @@ -3415,8 +3417,8 @@ BView::StrokeLine(BPoint pt0, BPoint pt1, ::pattern pattern) _UpdatePattern(pattern); ViewStrokeLineInfo info; - info.startPoint = pt0; - info.endPoint = pt1; + info.startPoint = start; + info.endPoint = end; fOwner->fLink->StartMessage(AS_STROKE_LINE); fOwner->fLink->Attach(info); @@ -3531,7 +3533,7 @@ BView::BeginLineArray(int32 count) void -BView::AddLine(BPoint pt0, BPoint pt1, rgb_color col) +BView::AddLine(BPoint start, BPoint end, rgb_color color) { if (fOwner == NULL) return; @@ -3543,9 +3545,9 @@ BView::AddLine(BPoint pt0, BPoint pt1, rgb_color col) const uint32 &arrayCount = fCommArray->count; if (arrayCount < fCommArray->maxCount) { - fCommArray->array[arrayCount].startPoint = pt0; - fCommArray->array[arrayCount].endPoint = pt1; - fCommArray->array[arrayCount].color = col; + fCommArray->array[arrayCount].startPoint = start; + fCommArray->array[arrayCount].endPoint = end; + fCommArray->array[arrayCount].color = color; fCommArray->count++; } @@ -3977,6 +3979,7 @@ BView::RemoveChild(BView* child) return child->RemoveSelf(); } + int32 BView::CountChildren() const { @@ -4205,18 +4208,19 @@ BView::GetSupportedSuites(BMessage* data) BHandler* -BView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, - int32 what, const char* property) +BView::ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier, + int32 what, const char* property) { - if (msg->what == B_WINDOW_MOVE_BY - || msg->what == B_WINDOW_MOVE_TO) + if (message->what == B_WINDOW_MOVE_BY + || message->what == B_WINDOW_MOVE_TO) { return this; + } BPropertyInfo propertyInfo(sViewPropInfo); status_t err = B_BAD_SCRIPT_SYNTAX; BMessage replyMsg(B_REPLY); - switch (propertyInfo.FindMatch(msg, index, specifier, what, property)) { + switch (propertyInfo.FindMatch(message, index, specifier, what, property)) { case 0: case 1: case 3: @@ -4224,7 +4228,7 @@ BView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, case 2: if (fShelf) { - msg->PopSpecifier(); + message->PopSpecifier(); return fShelf; } @@ -4269,7 +4273,7 @@ BView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, } if (child != NULL) { - msg->PopSpecifier(); + message->PopSpecifier(); return child; } @@ -4282,7 +4286,7 @@ BView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, } default: - return BHandler::ResolveSpecifier(msg, index, specifier, what, + return BHandler::ResolveSpecifier(message, index, specifier, what, property); } @@ -4296,16 +4300,16 @@ BView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, } replyMsg.AddInt32("error", err); - msg->SendReply(&replyMsg); + message->SendReply(&replyMsg); return NULL; } void -BView::MessageReceived(BMessage* msg) +BView::MessageReceived(BMessage* message) { - if (!msg->HasSpecifiers()) { - switch (msg->what) { + if (!message->HasSpecifiers()) { + switch (message->what) { case B_VIEW_RESIZED: // By the time the message arrives, the bounds may have // changed already, that's why we don't use the values @@ -4320,14 +4324,14 @@ BView::MessageReceived(BMessage* msg) case B_MOUSE_IDLE: { BPoint where; - if (msg->FindPoint("be:view_where", &where) != B_OK) + if (message->FindPoint("be:view_where", &where) != B_OK) break; BToolTip* tip; if (GetToolTipAt(where, &tip)) ShowToolTip(tip); else - BHandler::MessageReceived(msg); + BHandler::MessageReceived(message); break; } @@ -4337,15 +4341,15 @@ BView::MessageReceived(BMessage* msg) BScrollBar* vertical = ScrollBar(B_VERTICAL); if (horizontal == NULL && vertical == NULL) { // Pass the message to the next handler - BHandler::MessageReceived(msg); + BHandler::MessageReceived(message); break; } float deltaX = 0.0f, deltaY = 0.0f; if (horizontal != NULL) - msg->FindFloat("be:wheel_delta_x", &deltaX); + message->FindFloat("be:wheel_delta_x", &deltaX); if (vertical != NULL) - msg->FindFloat("be:wheel_delta_y", &deltaY); + message->FindFloat("be:wheel_delta_y", &deltaY); if (deltaX == 0.0f && deltaY == 0.0f) break; @@ -4361,7 +4365,7 @@ BView::MessageReceived(BMessage* msg) } default: - BHandler::MessageReceived(msg); + BHandler::MessageReceived(message); break; } @@ -4377,17 +4381,20 @@ BView::MessageReceived(BMessage* msg) int32 what; const char* property; - if (msg->GetCurrentSpecifier(&index, &specifier, &what, &property) != B_OK) - return BHandler::MessageReceived(msg); + if (message->GetCurrentSpecifier(&index, &specifier, &what, &property) + != B_OK) { + return BHandler::MessageReceived(message); + } BPropertyInfo propertyInfo(sViewPropInfo); - switch (propertyInfo.FindMatch(msg, index, &specifier, what, property)) { + switch (propertyInfo.FindMatch(message, index, &specifier, what, + property)) { case 0: - if (msg->what == B_GET_PROPERTY) { + if (message->what == B_GET_PROPERTY) { err = replyMsg.AddRect("result", Frame()); - } else if (msg->what == B_SET_PROPERTY) { + } else if (message->what == B_SET_PROPERTY) { BRect newFrame; - err = msg->FindRect("data", &newFrame); + err = message->FindRect("data", &newFrame); if (err == B_OK) { MoveTo(newFrame.LeftTop()); ResizeTo(newFrame.Width(), newFrame.Height()); @@ -4395,11 +4402,11 @@ BView::MessageReceived(BMessage* msg) } break; case 1: - if (msg->what == B_GET_PROPERTY) { + if (message->what == B_GET_PROPERTY) { err = replyMsg.AddBool("result", IsHidden()); - } else if (msg->what == B_SET_PROPERTY) { + } else if (message->what == B_SET_PROPERTY) { bool newHiddenState; - err = msg->FindBool("data", &newHiddenState); + err = message->FindBool("data", &newHiddenState); if (err == B_OK) { if (newHiddenState == true) Hide(); @@ -4412,7 +4419,7 @@ BView::MessageReceived(BMessage* msg) err = replyMsg.AddInt32("result", CountChildren()); break; default: - return BHandler::MessageReceived(msg); + return BHandler::MessageReceived(message); } if (err != B_OK) { @@ -4426,7 +4433,7 @@ BView::MessageReceived(BMessage* msg) replyMsg.AddInt32("error", err); } - msg->SendReply(&replyMsg); + message->SendReply(&replyMsg); } @@ -4751,15 +4758,6 @@ BView::IsLayoutValid() const } -/*! \brief Service call for BView derived classes reenabling - InvalidateLayout() notifications. - - BLayout & BView will avoid calling InvalidateLayout on views that have - already been invalidated, but if the view caches internal layout information - which it updates in methods other than DoLayout(), it has to invoke this - method, when it has done so, since otherwise the information might become - obsolete without the layout noticing. -*/ void BView::ResetLayoutInvalidation() { diff --git a/src/kits/network/interfaces.cpp b/src/kits/network/interfaces.cpp index 05871ef4ca..f0a7faffdd 100644 --- a/src/kits/network/interfaces.cpp +++ b/src/kits/network/interfaces.cpp @@ -106,16 +106,27 @@ if_nameindex(void) if (interfaceArray == NULL) return NULL; - for (int i = 0; i < count; i++) { - interfaceArray[i].if_index = interfaces->ifr_index; - interfaceArray[i].if_name = strdup(interfaces->ifr_name); + int i = 0; + while (count > 0) { + // retrieve interface index + ifreq request; + strlcpy(((struct ifreq&)request).ifr_name, interfaces->ifr_name, + IF_NAMESIZE); + + if (ioctl(socket.FD(), SIOCGIFINDEX, &request, + sizeof(struct ifreq)) >= 0) { + interfaceArray[i].if_index = request.ifr_index; + interfaceArray[i].if_name = strdup(interfaces->ifr_name); + i++; + } interfaces = (ifreq*)((char*)interfaces + _SIZEOF_ADDR_IFREQ(interfaces[0])); + count--; } - interfaceArray[count].if_index = 0; - interfaceArray[count].if_name = NULL; + interfaceArray[i].if_index = 0; + interfaceArray[i].if_name = NULL; return interfaceArray; } diff --git a/src/kits/shared/ExpressionParser.cpp b/src/kits/shared/ExpressionParser.cpp index b75c0e2c79..fbc416b242 100644 --- a/src/kits/shared/ExpressionParser.cpp +++ b/src/kits/shared/ExpressionParser.cpp @@ -21,32 +21,33 @@ static const int32 kMaxDecimalPlaces = 32; -enum { - TOKEN_IDENTIFIER = 0, +enum { + TOKEN_NONE = 0, + TOKEN_IDENTIFIER, TOKEN_CONSTANT, - TOKEN_PLUS, - TOKEN_MINUS, + TOKEN_END_OF_LINE = '\n', - TOKEN_STAR, - TOKEN_SLASH, - TOKEN_MODULO, + TOKEN_PLUS = '+', + TOKEN_MINUS = '-', - TOKEN_POWER, - TOKEN_FACTORIAL, + TOKEN_STAR = '*', + TOKEN_SLASH = '/', + TOKEN_MODULO = '%', - TOKEN_OPENING_BRACKET, - TOKEN_CLOSING_BRACKET, + TOKEN_POWER = '^', + TOKEN_FACTORIAL = '!', - TOKEN_AND, - TOKEN_OR, - TOKEN_NOT, + TOKEN_OPENING_BRACKET = '(', + TOKEN_CLOSING_BRACKET = ')', - TOKEN_NONE, - TOKEN_END_OF_LINE + TOKEN_AND = '&', + TOKEN_OR = '|', + TOKEN_NOT = '~' }; + struct ExpressionParser::Token { Token() : string(""), @@ -218,50 +219,25 @@ class ExpressionParser::Tokenizer { int32 type = TOKEN_NONE; switch (*fCurrentChar) { - case '+': - type = TOKEN_PLUS; + case TOKEN_PLUS: + case TOKEN_MINUS: + case TOKEN_STAR: + case TOKEN_SLASH: + case TOKEN_MODULO: + case TOKEN_POWER: + case TOKEN_FACTORIAL: + case TOKEN_OPENING_BRACKET: + case TOKEN_CLOSING_BRACKET: + case TOKEN_AND: + case TOKEN_OR: + case TOKEN_NOT: + case TOKEN_END_OF_LINE: + type = *fCurrentChar; break; - case '-': - type = TOKEN_MINUS; - break; - case '*': - type = TOKEN_STAR; - break; - case '/': + case '\\': case ':': - type = TOKEN_SLASH; - break; - - case '%': - type = TOKEN_MODULO; - break; - case '^': - type = TOKEN_POWER; - break; - case '!': - type = TOKEN_FACTORIAL; - break; - - case '(': - type = TOKEN_OPENING_BRACKET; - break; - case ')': - type = TOKEN_CLOSING_BRACKET; - break; - - case '&': - type = TOKEN_AND; - break; - case '|': - type = TOKEN_OR; - break; - case '~': - type = TOKEN_NOT; - break; - - case '\n': - type = TOKEN_END_OF_LINE; + type = TOKEN_SLASH; break; case 'x': @@ -755,9 +731,40 @@ ExpressionParser::_EatToken(int32 type) { Token token = fTokenizer->NextToken(); if (token.type != type) { - BString temp("expected '"); - temp << (char)type << "' got '" << token.string << "'"; + BString expected; + switch (type) { + case TOKEN_IDENTIFIER: + expected = "an identifier"; + break; + + case TOKEN_CONSTANT: + expected = "a constant"; + break; + + case TOKEN_PLUS: + case TOKEN_MINUS: + case TOKEN_STAR: + case TOKEN_MODULO: + case TOKEN_POWER: + case TOKEN_FACTORIAL: + case TOKEN_OPENING_BRACKET: + case TOKEN_CLOSING_BRACKET: + case TOKEN_AND: + case TOKEN_OR: + case TOKEN_NOT: + expected << "'" << (char)type << "'"; + break; + + case TOKEN_SLASH: + expected = "'/', '\\', or ':'"; + break; + + case TOKEN_END_OF_LINE: + expected = "'\\n'"; + break; + } + BString temp; + temp << "Expected " << expected.String() << " got '" << token.string << "'"; throw ParseException(temp.String(), token.position); } } - diff --git a/src/kits/shared/Jamfile b/src/kits/shared/Jamfile index 2459568ac7..3ef2481b24 100644 --- a/src/kits/shared/Jamfile +++ b/src/kits/shared/Jamfile @@ -28,6 +28,7 @@ StaticLibrary libshared.a : NaturalCompare.cpp PromptWindow.cpp QueryFile.cpp + RegExp.cpp RWLockManager.cpp SHA256.cpp ShakeTrackingFilter.cpp diff --git a/src/kits/shared/RegExp.cpp b/src/kits/shared/RegExp.cpp new file mode 100644 index 0000000000..a305aa4a02 --- /dev/null +++ b/src/kits/shared/RegExp.cpp @@ -0,0 +1,394 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include + +#include + +#include + + +// #pragma mark - RegExp::Data + + +struct RegExp::Data : public BReferenceable { + Data(const char* pattern, PatternType patternType, bool caseSensitive) + : + BReferenceable() + { + // convert the shell pattern to a regular expression + BString patternString; + if (patternType == PATTERN_TYPE_WILDCARD) { + while (*pattern != '\0') { + char c = *pattern++; + switch (c) { + case '?': + patternString += '.'; + continue; + case '*': + patternString += ".*"; + continue; + case '[': + { + // find the matching ']' first + const char* end = pattern; + while (*end != ']') { + if (*end++ == '\0') { + fError = REG_EBRACK; + return; + } + } + + if (pattern == end) { + // Empty bracket expression. It will never match + // anything. Strictly speaking this is not + // considered an error, but we handle it like one. + fError = REG_EBRACK; + return; + } + + patternString += '['; + + // We need to avoid "[." ... ".]", "[=" ... "=]", and + // "[:" ... ":]" sequences, since those have special + // meaning in regular expressions. If we encounter + // a '[' followed by either of '.', '=', or ':', we + // replace the '[' by "[.[.]". + while (pattern < end) { + c = *pattern++; + if (c == '[' && pattern < end) { + switch (*pattern) { + case '.': + case '=': + case ':': + patternString += "[.[.]"; + continue; + } + } + patternString += c; + } + + pattern++; + patternString += ']'; + break; + } + + case '\\': + { + // Quotes the next character. Works the same way for + // regular expressions. + if (*pattern == '\0') { + fError = REG_EESCAPE; + return; + } + + patternString += '\\'; + patternString += *pattern++; + break; + } + + case '^': + case '.': + case '$': + case '(': + case ')': + case '|': + case '+': + case '{': + // need to be quoted + patternString += '\\'; + // fall through + default: + patternString += c; + break; + } + } + + pattern = patternString.String(); + } + + int flags = REG_EXTENDED; + if (!caseSensitive) + flags |= REG_ICASE; + + fError = regcomp(&fCompiledExpression, pattern, flags); + } + + ~Data() + { + if (fError == 0) + regfree(&fCompiledExpression); + } + + bool IsValid() const + { + return fError == 0; + } + + const regex_t* CompiledExpression() const + { + return &fCompiledExpression; + } + +private: + int fError; + regex_t fCompiledExpression; +}; + + +// #pragma mark - RegExp::MatchResultData + + +struct RegExp::MatchResultData : public BReferenceable { + MatchResultData(const regex_t* compiledExpression, const char* string) + : + BReferenceable(), + fMatchCount(0), + fMatches(NULL) + { + // Do the matching: Since we need to provide a buffer for the matches + // for regexec() to fill in, but don't know the number of matches + // beforehand, we need to guess and retry with a larger buffer, if it + // wasn't large enough. + size_t maxMatchCount = 32; + for (;;) { + fMatches = new regmatch_t[maxMatchCount]; + if (regexec(compiledExpression, string, maxMatchCount, fMatches, 0) + != 0) { + delete[] fMatches; + fMatches = NULL; + fMatchCount = 0; + break; + } + + if (fMatches[maxMatchCount - 1].rm_so == -1) { + // determine the match count + size_t lower = 0; + size_t upper = maxMatchCount; + while (lower < upper) { + size_t mid = (lower + upper) / 2; + if (fMatches[mid].rm_so == -1) + upper = mid; + else + lower = mid + 1; + } + fMatchCount = lower; + break; + } + + // buffer too small -- try again with larger buffer + delete[] fMatches; + fMatches = NULL; + maxMatchCount *= 2; + } + } + + ~MatchResultData() + { + delete[] fMatches; + } + + size_t MatchCount() const + { + return fMatchCount; + } + + const regmatch_t* Matches() const + { + return fMatches; + } + +private: + size_t fMatchCount; + regmatch_t* fMatches; +}; + + +// #pragma mark - RegExp + + +RegExp::RegExp() + : + fData(NULL) +{ +} + + +RegExp::RegExp(const char* pattern, PatternType patternType, + bool caseSensitive) + : + fData(NULL) +{ + SetPattern(pattern, patternType, caseSensitive); +} + + +RegExp::RegExp(const RegExp& other) + : + fData(other.fData) +{ + if (fData != NULL) + fData->AcquireReference(); +} + + +RegExp::~RegExp() +{ + if (fData != NULL) + fData->ReleaseReference(); +} + + +bool +RegExp::SetPattern(const char* pattern, PatternType patternType, + bool caseSensitive) +{ + if (fData != NULL) { + fData->ReleaseReference(); + fData = NULL; + } + + Data* newData = new(std::nothrow) Data(pattern, patternType, caseSensitive); + if (newData == NULL) + return false; + + BReference dataReference(newData, true); + if (!newData->IsValid()) + return false; + + fData = dataReference.Detach(); + return true; +} + + +RegExp::MatchResult +RegExp::Match(const char* string) const +{ + if (!IsValid()) + return MatchResult(); + + return MatchResult( + new(std::nothrow) MatchResultData(fData->CompiledExpression(), + string)); +} + + +RegExp& +RegExp::operator=(const RegExp& other) +{ + if (fData != NULL) + fData->ReleaseReference(); + + fData = other.fData; + + if (fData != NULL) + fData->AcquireReference(); + + return *this; +} + + +// #pragma mark - RegExp::MatchResult + + +RegExp::MatchResult::MatchResult() + : + fData(NULL) +{ +} + + +RegExp::MatchResult::MatchResult(MatchResultData* data) + : + fData(data) +{ +} + + +RegExp::MatchResult::MatchResult(const MatchResult& other) + : + fData(other.fData) +{ + if (fData != NULL) + fData->AcquireReference(); +} + + +RegExp::MatchResult::~MatchResult() +{ + if (fData != NULL) + fData->ReleaseReference(); +} + + +bool +RegExp::MatchResult::HasMatched() const +{ + return fData != NULL && fData->MatchCount() > 0; +} + + +size_t +RegExp::MatchResult::StartOffset() const +{ + return fData != NULL && fData->MatchCount() > 0 + ? fData->Matches()[0].rm_so : 0; +} + + +size_t +RegExp::MatchResult::EndOffset() const +{ + return fData != NULL && fData->MatchCount() > 0 + ? fData->Matches()[0].rm_eo : 0; +} + + +size_t +RegExp::MatchResult::GroupCount() const +{ + if (fData == NULL) + return 0; + + size_t matchCount = fData->MatchCount(); + return matchCount > 0 ? matchCount - 1 : 0; +} + + +size_t +RegExp::MatchResult::GroupStartOffsetAt(size_t index) const +{ + return fData != NULL && fData->MatchCount() > index + 1 + ? fData->Matches()[index + 1].rm_so : 0; +} + + +size_t +RegExp::MatchResult::GroupEndOffsetAt(size_t index) const +{ + return fData != NULL && fData->MatchCount() > index + 1 + ? fData->Matches()[index + 1].rm_eo : 0; +} + + +RegExp::MatchResult& +RegExp::MatchResult::operator=(const MatchResult& other) +{ + if (fData != NULL) + fData->ReleaseReference(); + + fData = other.fData; + + if (fData != NULL) + fData->AcquireReference(); + + return *this; +} diff --git a/src/kits/tracker/ContainerWindow.cpp b/src/kits/tracker/ContainerWindow.cpp index 57a701dc18..88b2bdd985 100644 --- a/src/kits/tracker/ContainerWindow.cpp +++ b/src/kits/tracker/ContainerWindow.cpp @@ -2764,9 +2764,10 @@ BContainerWindow::AddFileContextMenus(BMenu* menu) menu->AddItem(new BMenuItem(TrackerSettings().DontMoveFilesToTrash() ? B_TRANSLATE("Delete") : B_TRANSLATE("Move to Trash"), new BMessage(kMoveToTrash), 'T')); - - // add separator for copy to/move to items (navigation items) - menu->AddSeparatorItem(); + if (!IsPrintersDir()) { + // add separator for copy to/move to items (navigation items) + menu->AddSeparatorItem(); + } } else { menu->AddItem(new BMenuItem(B_TRANSLATE("Delete"), new BMessage(kDelete), 0)); diff --git a/src/kits/tracker/FilePanelPriv.cpp b/src/kits/tracker/FilePanelPriv.cpp index 70d8cc3432..c7994fccf4 100644 --- a/src/kits/tracker/FilePanelPriv.cpp +++ b/src/kits/tracker/FilePanelPriv.cpp @@ -675,6 +675,8 @@ TFilePanel::Init(const BMessage*) fDirMenuField = new BMenuField(rect, "DirMenuField", "", fDirMenu); fDirMenuField->MenuBar()->SetFont(be_plain_font); fDirMenuField->SetDivider(0); + fDirMenuField->MenuBar()->SetMaxContentWidth(rect.Width() - 26.0f); + // Make room for the icon fDirMenuField->MenuBar()->RemoveItem((int32)0); fDirMenu->SetMenuBar(fDirMenuField->MenuBar()); diff --git a/src/kits/tracker/SettingsViews.cpp b/src/kits/tracker/SettingsViews.cpp index 3e645d433e..0dfa0bb7dd 100644 --- a/src/kits/tracker/SettingsViews.cpp +++ b/src/kits/tracker/SettingsViews.cpp @@ -32,41 +32,42 @@ names are registered trademarks or trademarks of their respective holders. All rights reserved. */ -#include -#include "Commands.h" -#include "DeskWindow.h" -#include "Model.h" #include "SettingsViews.h" -#include "Tracker.h" -#include "WidgetAttributeText.h" #include #include #include +#include +#include #include -#include +#include #include #include -#include #include +#include +#include #include +#include "Commands.h" +#include "DeskWindow.h" +#include "Model.h" +#include "Tracker.h" +#include "WidgetAttributeText.h" + static const uint32 kSpaceBarSwitchColor = 'SBsc'; -static const float kItemExtraSpacing = 2.0f; -static const float kIndentSpacing = 12.0f; //TODO: defaults should be set in one place only (TrackerSettings.cpp) while // being accessible from here. // What about adding DefaultValue(), IsDefault() etc... methods to // xxxValueSetting ? static const uint8 kSpaceBarAlpha = 192; -static const rgb_color kDefaultUsedSpaceColor = {0, 203, 0, kSpaceBarAlpha}; +static const rgb_color kDefaultUsedSpaceColor = { 0, 203, 0, kSpaceBarAlpha }; static const rgb_color kDefaultFreeSpaceColor - = {255, 255, 255, kSpaceBarAlpha}; + = { 255, 255, 255, kSpaceBarAlpha }; static const rgb_color kDefaultWarningSpaceColor - = {203, 0, 0, kSpaceBarAlpha}; + = { 203, 0, 0, kSpaceBarAlpha }; static void @@ -193,21 +194,19 @@ DesktopSettingsView::DesktopSettingsView() const float spacing = be_control_look->DefaultItemSpacing(); - BGroupLayoutBuilder(this) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .Add(fShowDisksIconRadioButton) + .Add(fMountVolumesOntoDesktopRadioButton) .AddGroup(B_VERTICAL, 0) - .Add(fShowDisksIconRadioButton) - .Add(fMountVolumesOntoDesktopRadioButton) - .AddGroup(B_VERTICAL, 0) - .Add(fMountSharedVolumesOntoDesktopCheckBox) - .SetInsets(20, 0, 0, 0) + .Add(fMountSharedVolumesOntoDesktopCheckBox) + .SetInsets(spacing * 2, 0, 0, 0) .End() + .AddGlue() + .AddGroup(B_HORIZONTAL) + .Add(fMountButton) .AddGlue() - .AddGroup(B_HORIZONTAL) - .Add(fMountButton) - .AddGlue() .End() - .End() - .SetInsets(spacing, spacing, spacing, spacing); + .SetInsets(spacing); fMountButton->SetTarget(be_app); } @@ -439,24 +438,22 @@ WindowsSettingsView::WindowsSettingsView() const float spacing = be_control_look->DefaultItemSpacing(); - BGroupLayoutBuilder(this) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .AddGroup(B_VERTICAL, 0) - .AddGroup(B_VERTICAL, 0) - .Add(fShowFullPathInTitleBarCheckBox) - .Add(fSingleWindowBrowseCheckBox) + .Add(fShowFullPathInTitleBarCheckBox) + .Add(fSingleWindowBrowseCheckBox) .End() - .AddGroup(B_VERTICAL) - .Add(fShowNavigatorCheckBox) - .SetInsets(20, 0, 0, 0) + .AddGroup(B_VERTICAL) + .Add(fShowNavigatorCheckBox) + .SetInsets(spacing * 2, 0, 0, 0) .End() - .AddGroup(B_VERTICAL, 0) - .Add(fOutlineSelectionCheckBox) - .Add(fSortFolderNamesFirstCheckBox) - .Add(fTypeAheadFilteringCheckBox) + .AddGroup(B_VERTICAL, 0) + .Add(fOutlineSelectionCheckBox) + .Add(fSortFolderNamesFirstCheckBox) + .Add(fTypeAheadFilteringCheckBox) .End() .AddGlue() - .End() - .SetInsets(spacing, spacing, spacing, spacing); + .SetInsets(spacing); } @@ -733,27 +730,25 @@ SpaceBarSettingsView::SpaceBarSettingsView() B_TRANSLATE("Warning space color"), new BMessage(kSpaceBarSwitchColor))); - BBox* box = new BBox("box"); - box->SetLabel(fColorPicker = new BMenuField("menu", NULL, menu)); + fColorPicker = new BMenuField("menu", NULL, menu); - fColorControl = new BColorControl(BPoint(8, - fColorPicker->Bounds().Height() + 8 + kItemExtraSpacing), + fColorControl = new BColorControl(BPoint(0, 0), B_CELLS_16x16, 1, "SpaceColorControl", new BMessage(kSpaceBarColorChanged)); fColorControl->SetValue(TrackerSettings().UsedSpaceColor()); - box->AddChild(fColorControl); - const float spacing = be_control_look->DefaultItemSpacing(); + BBox* box = new BBox("box"); + box->SetLabel(fColorPicker); + box->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL) + .Add(fColorControl) + .SetInsets(B_USE_DEFAULT_SPACING) + .View()); - BGroupLayout* layout = GroupLayout(); - layout->SetOrientation(B_VERTICAL); - layout->SetSpacing(0); - BGroupLayoutBuilder(layout) + BLayoutBuilder::Group<>(this, B_VERTICAL) .Add(fSpaceBarShowCheckBox) .Add(box) .AddGlue() - .SetInsets(spacing, spacing, spacing, spacing); - + .SetInsets(B_USE_DEFAULT_SPACING); } diff --git a/src/kits/tracker/SettingsViews.h b/src/kits/tracker/SettingsViews.h index 68ce03484f..b06cdd5f50 100644 --- a/src/kits/tracker/SettingsViews.h +++ b/src/kits/tracker/SettingsViews.h @@ -35,19 +35,19 @@ All rights reserved. #define _SETTINGS_VIEWS -#include #include -#include -#include -#include #include "TrackerSettings.h" const uint32 kSettingsContentsModified = 'Scmo'; + class BButton; +class BCheckBox; +class BColorControl; class BMenuField; +class BRadioButton; class BStringView; @@ -69,6 +69,7 @@ class SettingsView : public BGroupView { typedef BGroupView _inherited; }; + class DesktopSettingsView : public SettingsView { public: DesktopSettingsView(); @@ -101,6 +102,7 @@ class DesktopSettingsView : public SettingsView { typedef SettingsView _inherited; }; + class WindowsSettingsView : public SettingsView { public: WindowsSettingsView(); @@ -134,6 +136,7 @@ class WindowsSettingsView : public SettingsView { typedef SettingsView _inherited; }; + class SpaceBarSettingsView : public SettingsView { public: SpaceBarSettingsView(); diff --git a/src/libs/edit/Jamfile b/src/libs/edit/Jamfile index 6363d5f04b..0650210877 100644 --- a/src/libs/edit/Jamfile +++ b/src/libs/edit/Jamfile @@ -2,7 +2,7 @@ SubDir HAIKU_TOP src libs edit ; SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ; -UseLibraryHeaders termcap ; +UseLibraryHeaders ncurses ; UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) headers libs ncurses ] : true ; diff --git a/src/libs/fluidsynth/src/fluid_chan.c b/src/libs/fluidsynth/src/fluid_chan.c index 3406c4ba85..d007e4d2e7 100644 --- a/src/libs/fluidsynth/src/fluid_chan.c +++ b/src/libs/fluidsynth/src/fluid_chan.c @@ -268,9 +268,9 @@ fluid_channel_cc(fluid_channel_t* chan, int num, int value) fluid_channel_pitch_wheel_sens (chan, value); /* Set bend range in semitones */ /* FIXME - Handle LSB? (Fine bend range in cents) */ break; - case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over 1 semitone (+/- 50 cents, 8192 = center) */ + case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over +/-1 semitone (+/- 100 cents, 8192 = center) */ fluid_synth_set_gen(chan->synth, chan->channum, GEN_FINETUNE, - (data - 8192) / 8192.0 * 50.0); + (data - 8192) / 8192.0 * 100.0); break; case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */ fluid_synth_set_gen(chan->synth, chan->channum, GEN_COARSETUNE, diff --git a/src/libs/ncurses/Jamfile b/src/libs/ncurses/Jamfile index 8478937872..297bbd67b6 100644 --- a/src/libs/ncurses/Jamfile +++ b/src/libs/ncurses/Jamfile @@ -1,3 +1,4 @@ SubDir HAIKU_TOP src libs ncurses ; SubInclude HAIKU_TOP src libs ncurses ncurses ; +SubInclude HAIKU_TOP src libs ncurses progs ; diff --git a/src/libs/ncurses/include/ncurses_cfg.h b/src/libs/ncurses/include/ncurses_cfg.h index dd42d03393..95a7b68828 100644 --- a/src/libs/ncurses/include/ncurses_cfg.h +++ b/src/libs/ncurses/include/ncurses_cfg.h @@ -51,12 +51,12 @@ #define HAVE_LONG_FILE_NAMES 1 #define MIXEDCASE_FILENAMES 1 #define USE_DATABASE 1 -#define TERMINFO_DIRS "/usr/local/share/terminfo" -#define TERMINFO "/usr/local/share/terminfo" +#define TERMINFO_DIRS "/boot/common/data/terminfo" +#define TERMINFO "/boot/common/data/terminfo" #define TERMPATH "/etc/termcap" #define HAVE_BIG_CORE 1 -#define PURE_TERMINFO 0 -#define USE_TERMCAP 1 +#define PURE_TERMINFO 1 +#define USE_TERMCAP 0 #define USE_HOME_TERMINFO 1 #define USE_ROOT_ENVIRON 1 #define HAVE_REMOVE 1 diff --git a/src/libs/ncurses/progs/Jamfile b/src/libs/ncurses/progs/Jamfile new file mode 100644 index 0000000000..5cb817e3e3 --- /dev/null +++ b/src/libs/ncurses/progs/Jamfile @@ -0,0 +1,32 @@ +SubDir HAIKU_TOP src libs ncurses progs ; + +SubDirCcFlags -O2 -DHAVE_CONFIG_H -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=199506L -DNDEBUG ; + +SubDirSysHdrs $(SUBDIR) ; +SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) include ] ; + +BinCommand tput : + tput.c + : libncurses.a : ; + +BinCommand infocmp : + dump_entry.c + infocmp.c + : libncurses.a : ; + +BinCommand tset : + tset.c + : libncurses.a : ; + +BinCommand clear : + clear.c + : libncurses.a : ; + +BinCommand toe : + toe.c + : libncurses.a : ; + +BinCommand tic : + dump_entry.c + tic.c + : libncurses.a : ; diff --git a/src/libs/termcap/COPYING b/src/libs/termcap/COPYING deleted file mode 100644 index d60c31a97a..0000000000 --- a/src/libs/termcap/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - 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/src/libs/termcap/ChangeLog b/src/libs/termcap/ChangeLog deleted file mode 100644 index 335a2f7ee9..0000000000 --- a/src/libs/termcap/ChangeLog +++ /dev/null @@ -1,180 +0,0 @@ -2002-02-25 Gary Wong - - * version.c: Version 1.3.1. - - * configure.in: Update obselete macros. - - * termcap.src: Regenerated from version 11.0.1 master file. - - * tparam.c [!emacs]: Move #define of bcopy to after - #include . Reported by Oleg Kornilov and Iyer Viswanathan. - - * termcap.c [!emacs]: Replace ospeed for building standalone - libtermcap, for binary compatibility. - -2001-05-28 Gerd Moellmann - - * termcap.c (speeds): Put in #if 0. - -2000-12-08 Gerd Moellmann - - * tparam.c (tparam1): Change the way buffers are reallocated to be - portable and less obfuscated. - - * termcap.c (tgetent): Change the way buffers are reallocated to - be portable and less obfuscated. - -2000-11-19 Gerd Moellmann - - * termcap.c (ospeed): Remove. - (tputs) [!emacs]: Remove unused code. - (tgetent): Avoid a compiler warning. - -2000-06-20 Dave Love - - * tparam.c [emacs]: Include lisp.h. - - * termcap.c [emacs]: Test HAVE_FCNTL_H, not USG5. Include lisp.h - and unistd.h. - -2000-04-13 Gerd Moellmann - - * tparam.c (tparam1): Abort when encountering an unknown `%'-specifier. - -Wed Aug 16 20:45:44 1995 David J. MacKenzie - - * version.c: Version 1.3. - - * termcap.c (tgetent): Use the user-supplied buffer even if we - don't find a matching terminal, so the program can set the buffer - if they want (`less' does this). From Bob Pegram - . - -Wed Jul 26 11:44:51 1995 David J. MacKenzie - - * termcap.c: TERMCAP_NAME -> TERMCAP_FILE. - - * configure.in: Add --enable-install-termcap and --with-termcap - options. - - * Makefile.in: Add hooks for new configure options. - - * Makefile.in (DISTFILES): Add termcap.src. - (DEFS): Remove -DNO_ARG_ARRAY. - (install-data, uninstall-data): New targets. - - * tparam.c (tparam): Remove arg array version and the #ifdef. - - * termcap.c: Move #define of bcopy to after #include . - - * termcap.h: Prototype the arg to the tputs outfun arg. - - * Makefile.in: realclean -> maintainer-clean. Use @prefix@ and - @exec_prefix@. - - * Makefile.in (DISTFILES): Add install-sh. - -Fri Apr 7 14:57:45 1995 Richard Stallman - - * termcap.c (tgetent): Don't try to return the allocated address. - Always return 1 if successful. - -Tue Feb 14 02:34:43 1995 Richard Stallman - - * termcap.c (speeds): Make it ints. Add some higher speeds. - (tputs) [emacs]: If speed is high, convert to smaller units. - (tputs): Really use SPEED to calculate PADCOUNT. - -Sat Dec 17 07:20:24 1994 Richard Stallman - - * termcap.c (tgetst1): Let ^? stand for DEL character. - -Thu Jun 30 04:35:50 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * configure.in: Use AC_HAVE_HEADERS instead of AC_UNISTD_H. - Add AC_PROG_RANLIB. - * Makefile.in (AR, RANLIB): New variables. - (install, libtermcap.a): Use them instead of hard-wired commands. - -Sat Jun 4 12:21:41 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * termcap.c [HAVE_CONFIG_H]: Include , and include - #ifdef USG5, so we get O_* defns. - -Wed May 25 19:05:30 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * termcap.c (O_RDONLY): Define to 0 if not already defined. - (tgetent): Use O_RDONLY instead of explicit 0 in call to open. - -Wed Jan 5 22:20:15 1993 Morten Welinder (terra@diku.dk) - - * termcap.c (tgetent) [INTERNAL_TERMINAL]: Fake internal terminal - without reading any files. - (valid_file_name, tgetent) [MSDOS]: Drive letter support. - (tgetent) [MSDOS]: Use text mode for database. - -Fri Dec 17 00:22:43 1993 Mike Long (mike.long@analog.com) - - * termcap.c (tgetent): Replaced literal filenames for termcap - database with preprocessor symbol TERMCAP_NAME. - (TERMCAP_NAME): Define if not defined. - -Fri Sep 10 00:35:07 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * Makefile.in (.c.o): Put -I. before -I$(srcdir). - * termcap.c: Include instead of "config.h". - * tparam.c: Likewise. - -Thu Jul 29 20:53:30 1993 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu) - - * Makefile.in (config.status): Run config.status --recheck, not - configure, to get the right args passed. - -Thu Apr 15 12:45:10 1993 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu) - - * Version 1.2. - - * tparam.c [!emacs] (xmalloc, xrealloc, memory_out): New functions. - (tparam1): Use them. - - * termcap.c, tparam.c: Use NULL or '\0' where appropriate - instead of 0. Rename some vars. - * termcap.c (tgetent): If EOF is reached on termcap file, - free allocated resources before returning. - - * termcap.c (tgetent): Use /etc/termcap if TERMCAP is an entry - for a term type other than TERM. - From pjr@jet.UK (Paul J Rippin). - -Sat Apr 10 23:55:12 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) - - * tparam.c (tparam1): Don't set the 0200 bit on a non-0 character code. - From junio@twinsun.COM (Junio Hamano). - -Tue Dec 8 22:02:15 1992 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu) - - * termcap.c, tparam.c: Use HAVE_STRING_H instead of USG. - -Thu Dec 3 13:47:56 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) - - * termcap.c, tparam.c [HAVE_CONFIG_H]: Include config.h. - -Fri Oct 23 12:35:29 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) - - * termcap.h [__STDC__]: Add consts. From Franc,ois Pinard. - -Tue Oct 13 15:52:21 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) - - * Version 1.1. - -Tue Sep 29 21:04:39 1992 David J. MacKenzie (djm@geech.gnu.ai.mit.edu) - - * termcap.[ch], tparam.c: Fix some lint. - - * version.c: New file. - -Local Variables: -mode: indented-text -left-margin: 8 -version-control: never -End: diff --git a/src/libs/termcap/INSTALL b/src/libs/termcap/INSTALL deleted file mode 100644 index 50dbe439d0..0000000000 --- a/src/libs/termcap/INSTALL +++ /dev/null @@ -1,183 +0,0 @@ -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If at some point `config.cache' -contains results you don't want to keep, you may remove or edit it. - - The file `configure.in' is used to create `configure' by a program -called `autoconf'. You only need `configure.in' if you want to change -it or regenerate `configure' using a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure - -Or on systems that have the `env' program, you can do it like this: - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not supports the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' can not figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it can not guess the host type, give it the -`--host=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name with three fields: - CPU-COMPANY-SYSTEM - -See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the host type. - - If you are building compiler tools for cross-compiling, you can also -use the `--target=TYPE' option to select the type of system they will -produce code for and the `--build=TYPE' option to select the type of -system on which you are compiling the package. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Operation Controls -================== - - `configure' recognizes the following options to control how it -operates. - -`--cache-file=FILE' - Use and save the results of the tests in FILE instead of - `./config.cache'. Set FILE to `/dev/null' to disable caching, for - debugging `configure'. - -`--help' - Print a summary of the options to `configure', and exit. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--version' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`configure' also accepts some other, not widely useful, options. - diff --git a/src/libs/termcap/Jamfile b/src/libs/termcap/Jamfile index dd5667474f..4f3f7fea61 100644 --- a/src/libs/termcap/Jamfile +++ b/src/libs/termcap/Jamfile @@ -1,16 +1,5 @@ SubDir HAIKU_TOP src libs termcap ; -SetSubDirSupportedPlatformsBeOSCompatible ; - -# set some additional defines -{ - SubDirCcFlags -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DTERMCAP_FILE=\'\"/etc/termcap\"\' -w ; -} - -StaticLibrary libtermcap.a : - termcap.c tparam.c version.c -; - # Build the /etc/termcap file. It's already ready to use, but we filter out the # comments. diff --git a/src/libs/termcap/Makefile.in b/src/libs/termcap/Makefile.in deleted file mode 100644 index 66e5d02f5f..0000000000 --- a/src/libs/termcap/Makefile.in +++ /dev/null @@ -1,138 +0,0 @@ -# Makefile for GNU termcap library. -# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -#### Start of system configuration section. #### - -srcdir = @srcdir@ -VPATH = @srcdir@ - -CC = @CC@ -AR = ar -RANLIB = @RANLIB@ - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ - -MAKEINFO = makeinfo - -DEFS = @DEFS@ -DTERMCAP_FILE=\"$(termcapfile)\" - -CFLAGS = -g - -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -# Directory in which to install libtermcap.a. -libdir = $(exec_prefix)/lib - -# Directory in which to install termcap.h. -includedir = $(prefix)/include - -# Directory in which to optionally also install termcap.h, -# so compilers besides gcc can find it by default. -# If it is empty or not defined, termcap.h will only be installed in -# includedir. -oldincludedir = /usr/include - -# Directory in which to install the documentation info files. -infodir = $(prefix)/info - -# File to which `install-data' should install the data file -# if --enable-install-termcap was given. -termcapfile = @termcapfile@ - -#### End of system configuration section. #### - -SHELL = /bin/sh - -SRCS = termcap.c tparam.c version.c -OBJS = termcap.o tparam.o version.o -HDRS = termcap.h -DISTFILES = $(SRCS) $(HDRS) ChangeLog COPYING README INSTALL NEWS \ -termcap.src termcap.texi termcap.info* \ -texinfo.tex Makefile.in configure configure.in mkinstalldirs install-sh - -all: libtermcap.a info - -.c.o: - $(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) $(CFLAGS) $< - -install: all installdirs @installdata@ - $(INSTALL_DATA) libtermcap.a $(libdir)/libtermcap.a - -$(RANLIB) $(libdir)/libtermcap.a - cd $(srcdir); $(INSTALL_DATA) termcap.h $(includedir)/termcap.h - -cd $(srcdir); test -z "$(oldincludedir)" || \ - $(INSTALL_DATA) termcap.h $(oldincludedir)/termcap.h - cd $(srcdir); for f in termcap.info*; \ - do $(INSTALL_DATA) $$f $(infodir)/$$f; done - -uninstall: @uninstalldata@ - rm -f $(libdir)/libtermcap.a $(includedir)/termcap.h - test -z "$(oldincludedir)" || rm -f $(oldincludedir)/termcap.h - rm -f $(infodir)/termcap.info* - -# These are separate targets to avoid trashing the user's existing -# termcap file unexpectedly. -install-data: - $(INSTALL_DATA) ${srcdir}/termcap.src ${termcapfile} - -uninstall-data: - rm -f ${termcapfile} - -installdirs: - $(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(libdir) \ - $(includedir) $(infodir) - -Makefile: Makefile.in config.status - $(SHELL) config.status -config.status: configure - $(SHELL) config.status --recheck -configure: configure.in - cd $(srcdir) && autoconf - -libtermcap.a: $(OBJS) - $(AR) rc $@ $(OBJS) - -$(RANLIB) $@ - -info: termcap.info - -termcap.info: termcap.texi - $(MAKEINFO) $(srcdir)/termcap.texi --output=$@ - -TAGS: $(SRCS) - etags $(SRCS) - -clean: - rm -f *.a *.o core - -mostlyclean: clean - -distclean: clean - rm -f Makefile config.status config.cache config.log - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "rebuilding the deleted files requires makeinfo." - rm -f TAGS *.info* - -dist: $(DISTFILES) - echo termcap-`sed -e '/version_string/!d' -e 's/[^0-9]*\([0-9a-z.]*\).*/\1/' -e q version.c` > .fname - rm -rf `cat .fname` - mkdir `cat .fname` - ln $(DISTFILES) `cat .fname` - tar chzf `cat .fname`.tar.gz `cat .fname` - rm -rf `cat .fname` .fname diff --git a/src/libs/termcap/NEWS b/src/libs/termcap/NEWS deleted file mode 100644 index 5116dd7d6f..0000000000 --- a/src/libs/termcap/NEWS +++ /dev/null @@ -1,25 +0,0 @@ -Major changes in release 1.3.1: - -Termcap data file updated. -Bug fixes and portability changes. - -Major changes in release 1.3: - -Termcap data file is now included in distribution and may optionally - be installed, or used in a non-default location. -Support for a fake internal terminal (no external files). -Higher tty speeds supported. -Portability tweaks. - -Major changes in release 1.2: - -For `%.', only set the high bit on NUL. -Fix a file descriptor and memory leak. -Add const in termcap.h prototypes. -Configuration improvements. - -Major changes in release 1.1: - -Fix portability problems. -Improve configuration and installation. -Fix compiler warnings. diff --git a/src/libs/termcap/README b/src/libs/termcap/README deleted file mode 100644 index ba1a19c93d..0000000000 --- a/src/libs/termcap/README +++ /dev/null @@ -1,34 +0,0 @@ -This is the GNU termcap library -- a library of C functions that -enable programs to send control strings to terminals in a way -independent of the terminal type. The GNU termcap library does not -place an arbitrary limit on the size of termcap entries, unlike most -other termcap libraries. - -Most of this package is also distributed with GNU Emacs, but it is -available in this separate distribution to make it easier to install -as -ltermcap. However, use of termcap is discouraged. Termcap is -being phased out in favor of the terminfo-based ncurses library, which -contains an emulation of the termcap library routines in addition to -an excellent curses implementation. ncurses is available from the -usual GNU archive sites. - -See the file INSTALL for compilation and installation instructions. -Additionally: - -This package contains termcap.src, the latest official termcap data -file. By default, it is not installed. The current version contains -some entries that are more than 1023 bytes long, which is the largest -value that is safe to use with the many historical applications that -only allocate a 1024 byte termcap buffer (telnet, for example). If -you make sure that all of your programs allocate buffers of at least -2500 bytes, or let the termcap library do it by passing a NULL -pointer, then it is safe to install the new termcap file, as described -below. - -You can give configure two special options: - --enable-install-termcap install the termcap data file - --with-termcap=FILE use data file FILE instead of /etc/termcap - -Please report any bugs in this library to bug-gnu-emacs@prep.ai.mit.edu. -You can check which version of the library you have by using the RCS -`ident' command on libtermcap.a. diff --git a/src/libs/termcap/configure b/src/libs/termcap/configure deleted file mode 100644 index 8a885fa5b4..0000000000 --- a/src/libs/termcap/configure +++ /dev/null @@ -1,998 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.4 -# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_help="$ac_help - --enable-install-termcap install the termcap data file" -ac_help="$ac_help - --with-termcap=FILE use data file FILE instead of /etc/termcap" - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE - -# Initialize some other variables. -subdirs= - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -build | --build | --buil | --bui | --bu | --b) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=PREFIX install architecture-dependent files in PREFIX - [same as prefix] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR ---enable and --with options recognized:$ac_help -EOF - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.4" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set LANG and LC_ALL to C if already set. -# These must not be set unconditionally because not all systems understand -# e.g. LANG=C (notably SCO). -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LANG+set}" = set; then LANG=C; export LANG; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=termcap.h - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5' - -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - - -# Check whether --enable-install-termcap or --disable-install-termcap was given. -enableval="$enable_install_termcap" -if test -n "$enableval"; then - if test $enableval = yes; then - installdata=install-data uninstalldata=uninstall-data - fi -fi - - -# Check whether --with-termcap or --without-termcap was given. -withval="$with_termcap" -if test -n "$withval"; then - termcapfile=$withval -else - termcapfile=/etc/termcap -fi - - -# Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5 | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 -if test $ac_cv_prog_gcc = yes; then - GCC=yes - if test "${CFLAGS+set}" != set; then - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_gcc_g=yes -else - ac_cv_prog_gcc_g=no -fi -rm -f conftest* - -fi - echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 - if test $ac_cv_prog_gcc_g = yes; then - CFLAGS="-g -O" - else - CFLAGS="-O" - fi - fi -else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" -fi - -# Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="ranlib" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - for ac_prog in ginstall installbsd scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - # OSF/1 installbsd also uses dspmsg, but is usable. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_ifs" - # As a last resort, use the slow shell script. - test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh" -fi - INSTALL="$ac_cv_path_install" -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # This must be in double quotes, not single quotes, because CPP may get - # substituted into the Makefile and "${CC-cc}" will confuse make. - CPP="${CC-cc} -E" - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext < -Syntax Error -EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext < -Syntax Error -EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - -for ac_hdr in string.h unistd.h -do -ac_safe=`echo "$ac_hdr" | tr './\055' '___'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./\055' '[A-Z]___'` - cat >> confdefs.h <&6 -fi -done - -# If we cannot run a trivial program, we must be cross compiling. -echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - ac_cv_c_cross=yes -else -cat > conftest.$ac_ext </dev/null; then - ac_cv_c_cross=no -else - ac_cv_c_cross=yes -fi -fi -rm -fr conftest* -fi -cross_compiling=$ac_cv_c_cross -echo "$ac_t""$ac_cv_c_cross" 1>&6 - -echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -#include -#include -EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - rm -rf conftest* - ac_cv_header_stdc=yes -else - echo "$ac_err" >&5 - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. -cat > conftest.$ac_ext < -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "memchr" >/dev/null 2>&1; then - : -else - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. -cat > conftest.$ac_ext < -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "free" >/dev/null 2>&1; then - : -else - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. -if test "$cross_compiling" = yes; then - ac_cv_header_stdc=no -else -cat > conftest.$ac_ext < -#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int main () { int i; for (i = 0; i < 256; i++) -if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); -exit (0); } - -EOF -eval $ac_link -if test -s conftest && (./conftest; exit) 2>/dev/null; then - : -else - ac_cv_header_stdc=no -fi -fi -rm -fr conftest* -fi -fi -echo "$ac_t""$ac_cv_header_stdc" 1>&6 -if test $ac_cv_header_stdc = yes; then - cat >> confdefs.h <<\EOF -#define STDC_HEADERS 1 -EOF - -fi - - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ - >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g -EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs - - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.4" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" - -trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 - -# Protect against being on the right side of a sed subst in config.status. -sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g; - s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF -$ac_vpsub -$extrasub -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@installdata@%$installdata%g -s%@uninstalldata@%$uninstalldata%g -s%@termcapfile@%$termcapfile%g -s%@CC@%$CC%g -s%@RANLIB@%$RANLIB%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@CPP@%$CPP%g - -CEOF -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust relative srcdir, etc. for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; - esac - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file -fi; done -rm -f conftest.subs - - - -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - diff --git a/src/libs/termcap/configure.in b/src/libs/termcap/configure.in deleted file mode 100644 index f3f944f9c5..0000000000 --- a/src/libs/termcap/configure.in +++ /dev/null @@ -1,23 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT(termcap.h) - -AC_ARG_ENABLE(install-termcap, -[ --enable-install-termcap install the termcap data file], -[if test $enableval = yes; then - installdata=install-data uninstalldata=uninstall-data - fi]) -AC_SUBST(installdata)dnl -AC_SUBST(uninstalldata)dnl - -AC_ARG_WITH(termcap, -[ --with-termcap=FILE use data file FILE instead of /etc/termcap], -termcapfile=$withval, termcapfile=/etc/termcap) -AC_SUBST(termcapfile)dnl - -AC_PROG_CC -AC_PROG_RANLIB -AC_PROG_INSTALL -AC_HAVE_HEADERS(string.h unistd.h) -AC_STDC_HEADERS - -AC_OUTPUT(Makefile) diff --git a/src/libs/termcap/install-sh b/src/libs/termcap/install-sh deleted file mode 100644 index 89fc9b098b..0000000000 --- a/src/libs/termcap/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -tranformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/src/libs/termcap/mkinstalldirs b/src/libs/termcap/mkinstalldirs deleted file mode 100644 index cd1fe0a794..0000000000 --- a/src/libs/termcap/mkinstalldirs +++ /dev/null @@ -1,32 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -errstatus=0 - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d in ${1+"$@"} ; do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" 1>&2 - mkdir "$pathcomp" || errstatus=$? - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# mkinstalldirs ends here diff --git a/src/libs/termcap/termcap.c b/src/libs/termcap/termcap.c deleted file mode 100644 index f44ba64a22..0000000000 --- a/src/libs/termcap/termcap.c +++ /dev/null @@ -1,818 +0,0 @@ -/* Work-alike for termcap, plus extra features. - Copyright (C) 1985, 86, 93, 94, 95, 2000, 2001 - Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Emacs config.h may rename various library functions such as malloc. */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef emacs - -#include /* xmalloc is here */ -/* Get the O_* definitions for open et al. */ -#include -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#else /* not emacs */ - -#ifdef STDC_HEADERS -#include -#include -#else -char *getenv (); -char *malloc (); -char *realloc (); -#endif - -/* Do this after the include, in case string.h prototypes bcopy. */ -#if (defined(HAVE_STRING_H) || defined(STDC_HEADERS)) && !defined(bcopy) -#define bcopy(s, d, n) memcpy ((d), (s), (n)) -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef _POSIX_VERSION -#include -#endif - -#endif /* not emacs */ - -#ifndef NULL -#define NULL (char *) 0 -#endif - -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif - -/* BUFSIZE is the initial size allocated for the buffer - for reading the termcap file. - It is not a limit. - Make it large normally for speed. - Make it variable when debugging, so can exercise - increasing the space dynamically. */ - -#ifndef BUFSIZE -#ifdef DEBUG -#define BUFSIZE bufsize - -int bufsize = 128; -#else -#define BUFSIZE 2048 -#endif -#endif - -#ifndef TERMCAP_FILE -#define TERMCAP_FILE "/etc/termcap" -#endif - -#ifndef emacs -static void -memory_out () -{ - write (2, "virtual memory exhausted\n", 25); - exit (1); -} - -static char * -xmalloc (size) - unsigned size; -{ - register char *tem = malloc (size); - - if (!tem) - memory_out (); - return tem; -} - -static char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - register char *tem = realloc (ptr, size); - - if (!tem) - memory_out (); - return tem; -} -#endif /* not emacs */ - -/* Looking up capabilities in the entry already found. */ - -/* The pointer to the data made by tgetent is left here - for tgetnum, tgetflag and tgetstr to find. */ -static char *term_entry; - -static char *tgetst1 (); - -/* Search entry BP for capability CAP. - Return a pointer to the capability (in BP) if found, - 0 if not found. */ - -static char * -find_capability (bp, cap) - register char *bp, *cap; -{ - for (; *bp; bp++) - if (bp[0] == ':' - && bp[1] == cap[0] - && bp[2] == cap[1]) - return &bp[4]; - return NULL; -} - -int -tgetnum (cap) - char *cap; -{ - register char *ptr = find_capability (term_entry, cap); - if (!ptr || ptr[-1] != '#') - return -1; - return atoi (ptr); -} - -int -tgetflag (cap) - char *cap; -{ - register char *ptr = find_capability (term_entry, cap); - return ptr && ptr[-1] == ':'; -} - -/* Look up a string-valued capability CAP. - If AREA is non-null, it points to a pointer to a block in which - to store the string. That pointer is advanced over the space used. - If AREA is null, space is allocated with `malloc'. */ - -char * -tgetstr (cap, area) - char *cap; - char **area; -{ - register char *ptr = find_capability (term_entry, cap); - if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~')) - return NULL; - return tgetst1 (ptr, area); -} - -#ifdef IS_EBCDIC_HOST -/* Table, indexed by a character in range 0200 to 0300 with 0200 subtracted, - gives meaning of character following \, or a space if no special meaning. - Sixteen characters per line within the string. */ - -static char esctab[] - = " \057\026 \047\014 \ - \025 \015 \ - \005 \013 \ - "; -#else -/* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted, - gives meaning of character following \, or a space if no special meaning. - Eight characters per line within the string. */ - -static char esctab[] - = " \007\010 \033\014 \ - \012 \ - \015 \011 \013 \ - "; -#endif - -/* PTR points to a string value inside a termcap entry. - Copy that value, processing \ and ^ abbreviations, - into the block that *AREA points to, - or to newly allocated storage if AREA is NULL. - Return the address to which we copied the value, - or NULL if PTR is NULL. */ - -static char * -tgetst1 (ptr, area) - char *ptr; - char **area; -{ - register char *p, *r; - register int c; - register int size; - char *ret; - register int c1; - - if (!ptr) - return NULL; - - /* `ret' gets address of where to store the string. */ - if (!area) - { - /* Compute size of block needed (may overestimate). */ - p = ptr; - while ((c = *p++) && c != ':' && c != '\n') - ; - ret = (char *) xmalloc (p - ptr + 1); - } - else - ret = *area; - - /* Copy the string value, stopping at null or colon. - Also process ^ and \ abbreviations. */ - p = ptr; - r = ret; - while ((c = *p++) && c != ':' && c != '\n') - { - if (c == '^') - { - c = *p++; - if (c == '?') - c = 0177; - else - c &= 037; - } - else if (c == '\\') - { - c = *p++; - if (c >= '0' && c <= '7') - { - c -= '0'; - size = 0; - - while (++size < 3 && (c1 = *p) >= '0' && c1 <= '7') - { - c *= 8; - c += c1 - '0'; - p++; - } - } -#ifdef IS_EBCDIC_HOST - else if (c >= 0200 && c < 0360) - { - c1 = esctab[(c & ~0100) - 0200]; - if (c1 != ' ') - c = c1; - } -#else - else if (c >= 0100 && c < 0200) - { - c1 = esctab[(c & ~040) - 0100]; - if (c1 != ' ') - c = c1; - } -#endif - } - *r++ = c; - } - *r = '\0'; - /* Update *AREA. */ - if (area) - *area = r + 1; - return ret; -} - -/* Outputting a string with padding. */ - -#ifndef emacs -short ospeed; -/* If OSPEED is 0, we use this as the actual baud rate. */ -int tputs_baud_rate; -#endif -char PC; - -#ifndef emacs -/* Actual baud rate if positive; - - baud rate / 100 if negative. */ - -static int speeds[] = - { -#ifdef VMS - 0, 50, 75, 110, 134, 150, -3, -6, -12, -18, - -20, -24, -36, -48, -72, -96, -192 -#else /* not VMS */ - 0, 50, 75, 110, 135, 150, -2, -3, -6, -12, - -18, -24, -48, -96, -192, -288, -384, -576, -1152 -#endif /* not VMS */ - }; - -#endif /* not emacs */ - -void -tputs (str, nlines, outfun) - register char *str; - int nlines; - register int (*outfun) (); -{ - register int padcount = 0; - register int speed; - -#ifdef emacs - extern int baud_rate; - speed = baud_rate; - /* For quite high speeds, convert to the smaller - units to avoid overflow. */ - if (speed > 10000) - speed = - speed / 100; -#else - if (ospeed == 0) - speed = tputs_baud_rate; - else - speed = speeds[ospeed]; -#endif - - if (!str) - return; - - while (*str >= '0' && *str <= '9') - { - padcount += *str++ - '0'; - padcount *= 10; - } - if (*str == '.') - { - str++; - padcount += *str++ - '0'; - } - if (*str == '*') - { - str++; - padcount *= nlines; - } - while (*str) - (*outfun) (*str++); - - /* PADCOUNT is now in units of tenths of msec. - SPEED is measured in characters per 10 seconds - or in characters per .1 seconds (if negative). - We use the smaller units for larger speeds to avoid overflow. */ - padcount *= speed; - padcount += 500; - padcount /= 1000; - if (speed < 0) - padcount = -padcount; - else - { - padcount += 50; - padcount /= 100; - } - - while (padcount-- > 0) - (*outfun) (PC); -} - -/* Finding the termcap entry in the termcap data base. */ - -struct termcap_buffer - { - char *beg; - int size; - char *ptr; - int ateof; - int full; - }; - -/* Forward declarations of static functions. */ - -static int scan_file (); -static char *gobble_line (); -static int compare_contin (); -static int name_match (); - -#ifdef VMS - -#include -#include -#include - -static int -valid_filename_p (fn) - char *fn; -{ - struct FAB fab = cc$rms_fab; - struct NAM nam = cc$rms_nam; - char esa[NAM$C_MAXRSS]; - - fab.fab$l_fna = fn; - fab.fab$b_fns = strlen(fn); - fab.fab$l_nam = &nam; - fab.fab$l_fop = FAB$M_NAM; - - nam.nam$l_esa = esa; - nam.nam$b_ess = sizeof esa; - - return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL; -} - -#else /* !VMS */ - -#ifdef MSDOS /* MW, May 1993 */ -static int -valid_filename_p (fn) - char *fn; -{ - return *fn == '/' || fn[1] == ':'; -} -#else -#define valid_filename_p(fn) (*(fn) == '/') -#endif - -#endif /* !VMS */ - -/* Find the termcap entry data for terminal type NAME - and store it in the block that BP points to. - Record its address for future use. - - If BP is null, space is dynamically allocated. - - Return -1 if there is some difficulty accessing the data base - of terminal types, - 0 if the data base is accessible but the type NAME is not defined - in it, and some other value otherwise. */ - -int -tgetent (bp, name) - char *bp, *name; -{ - register char *termcap_name; - register int fd; - struct termcap_buffer buf; - register char *bp1; - char *tc_search_point; - char *term; - int malloc_size = 0; - register int c; - char *tcenv = NULL; /* TERMCAP value, if it contains :tc=. */ - char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */ - int filep; - -// bonefish: HACK to avoid problems. Our termcap entries are longer than the -// 2KB that are advised as the size of the buffer to be passed to tgetent(). -// This leads to nasty problems, so just always allocate a buffer. -bp = NULL; - -#ifdef INTERNAL_TERMINAL - /* For the internal terminal we don't want to read any termcap file, - so fake it. */ - if (!strcmp (name, "internal")) - { - term = INTERNAL_TERMINAL; - if (!bp) - { - malloc_size = 1 + strlen (term); - bp = (char *) xmalloc (malloc_size); - } - strcpy (bp, term); - goto ret; - } -#endif /* INTERNAL_TERMINAL */ - - /* For compatibility with programs like `less' that want to - put data in the termcap buffer themselves as a fallback. */ - if (bp) - term_entry = bp; - - termcap_name = getenv ("TERMCAP"); - if (termcap_name && *termcap_name == '\0') - termcap_name = NULL; -#if defined (MSDOS) && !defined (TEST) - if (termcap_name && (*termcap_name == '\\' - || *termcap_name == '/' - || termcap_name[1] == ':')) - dostounix_filename(termcap_name); -#endif - - filep = termcap_name && valid_filename_p (termcap_name); - - /* If termcap_name is non-null and starts with / (in the un*x case, that is), - it is a file name to use instead of /etc/termcap. - If it is non-null and does not start with /, - it is the entry itself, but only if - the name the caller requested matches the TERM variable. */ - - if (termcap_name && !filep && !strcmp (name, getenv ("TERM"))) - { - indirect = tgetst1 (find_capability (termcap_name, "tc"), (char **) 0); - if (!indirect) - { - if (!bp) - bp = termcap_name; - else - strcpy (bp, termcap_name); - goto ret; - } - else - { /* It has tc=. Need to read /etc/termcap. */ - tcenv = termcap_name; - termcap_name = NULL; - } - } - - if (!termcap_name || !filep) - termcap_name = TERMCAP_FILE; - - /* Here we know we must search a file and termcap_name has its name. */ - -#ifdef MSDOS - fd = open (termcap_name, O_RDONLY|O_TEXT, 0); -#else - fd = open (termcap_name, O_RDONLY, 0); -#endif - if (fd < 0) - return -1; - - buf.size = BUFSIZE; - /* Add 1 to size to ensure room for terminating null. */ - buf.beg = (char *) xmalloc (buf.size + 1); - term = indirect ? indirect : name; - - if (!bp) - { - malloc_size = indirect ? strlen (tcenv) + 1 : buf.size; - bp = (char *) xmalloc (malloc_size); - } - tc_search_point = bp1 = bp; - - if (indirect) - /* Copy the data from the environment variable. */ - { - strcpy (bp, tcenv); - bp1 += strlen (tcenv); - } - - while (term) - { - /* Scan the file, reading it via buf, till find start of main entry. */ - if (scan_file (term, fd, &buf) == 0) - { - close (fd); - free (buf.beg); - if (malloc_size) - free (bp); - return 0; - } - - /* Free old `term' if appropriate. */ - if (term != name) - free (term); - - /* If BP is malloc'd by us, make sure it is big enough. */ - if (malloc_size) - { - int offset1 = bp1 - bp, offset2 = tc_search_point - bp; - malloc_size = offset1 + buf.size; - bp = termcap_name = (char *) xrealloc (bp, malloc_size); - bp1 = termcap_name + offset1; - tc_search_point = termcap_name + offset2; - } - - /* Copy the line of the entry from buf into bp. */ - termcap_name = buf.ptr; - while ((*bp1++ = c = *termcap_name++) && c != '\n') - /* Drop out any \ newline sequence. */ - if (c == '\\' && *termcap_name == '\n') - { - bp1--; - termcap_name++; - } - *bp1 = '\0'; - - /* Does this entry refer to another terminal type's entry? - If something is found, copy it into heap and null-terminate it. */ - tc_search_point = find_capability (tc_search_point, "tc"); - term = tgetst1 (tc_search_point, (char **) 0); - } - - close (fd); - free (buf.beg); - - if (malloc_size) - bp = (char *) xrealloc (bp, bp1 - bp + 1); - - ret: - term_entry = bp; - return 1; -} - -/* Given file open on FD and buffer BUFP, - scan the file from the beginning until a line is found - that starts the entry for terminal type STR. - Return 1 if successful, with that line in BUFP, - or 0 if no entry is found in the file. */ - -static int -scan_file (str, fd, bufp) - char *str; - int fd; - register struct termcap_buffer *bufp; -{ - register char *end; - - bufp->ptr = bufp->beg; - bufp->full = 0; - bufp->ateof = 0; - *bufp->ptr = '\0'; - - lseek (fd, 0L, 0); - - while (!bufp->ateof) - { - /* Read a line into the buffer. */ - end = NULL; - do - { - /* if it is continued, append another line to it, - until a non-continued line ends. */ - end = gobble_line (fd, bufp, end); - } - while (!bufp->ateof && end[-2] == '\\'); - - if (*bufp->ptr != '#' - && name_match (bufp->ptr, str)) - return 1; - - /* Discard the line just processed. */ - bufp->ptr = end; - } - return 0; -} - -/* Return nonzero if NAME is one of the names specified - by termcap entry LINE. */ - -static int -name_match (line, name) - char *line, *name; -{ - register char *tem; - - if (!compare_contin (line, name)) - return 1; - /* This line starts an entry. Is it the right one? */ - for (tem = line; *tem && *tem != '\n' && *tem != ':'; tem++) - if (*tem == '|' && !compare_contin (tem + 1, name)) - return 1; - - return 0; -} - -static int -compare_contin (str1, str2) - register char *str1, *str2; -{ - register int c1, c2; - while (1) - { - c1 = *str1++; - c2 = *str2++; - while (c1 == '\\' && *str1 == '\n') - { - str1++; - while ((c1 = *str1++) == ' ' || c1 == '\t'); - } - if (c2 == '\0') - { - /* End of type being looked up. */ - if (c1 == '|' || c1 == ':') - /* If end of name in data base, we win. */ - return 0; - else - return 1; - } - else if (c1 != c2) - return 1; - } -} - -/* Make sure that the buffer <- BUFP contains a full line - of the file open on FD, starting at the place BUFP->ptr - points to. Can read more of the file, discard stuff before - BUFP->ptr, or make the buffer bigger. - - Return the pointer to after the newline ending the line, - or to the end of the file, if there is no newline to end it. - - Can also merge on continuation lines. If APPEND_END is - non-null, it points past the newline of a line that is - continued; we add another line onto it and regard the whole - thing as one line. The caller decides when a line is continued. */ - -static char * -gobble_line (fd, bufp, append_end) - int fd; - register struct termcap_buffer *bufp; - char *append_end; -{ - register char *end; - register int nread; - register char *buf = bufp->beg; - register char *tem; - - if (!append_end) - append_end = bufp->ptr; - - while (1) - { - end = append_end; - while (*end && *end != '\n') end++; - if (*end) - break; - if (bufp->ateof) - return buf + bufp->full; - if (bufp->ptr == buf) - { - if (bufp->full == bufp->size) - { - bufp->size *= 2; - /* Add 1 to size to ensure room for terminating null. */ - tem = (char *) xrealloc (buf, bufp->size + 1); - bufp->ptr = (bufp->ptr - buf) + tem; - append_end = (append_end - buf) + tem; - bufp->beg = buf = tem; - } - } - else - { - append_end -= bufp->ptr - buf; - bcopy (bufp->ptr, buf, bufp->full -= bufp->ptr - buf); - bufp->ptr = buf; - } - if (!(nread = read (fd, buf + bufp->full, bufp->size - bufp->full))) - bufp->ateof = 1; - bufp->full += nread; - buf[bufp->full] = '\0'; - } - return end + 1; -} - -#ifdef TEST - -#ifdef NULL -#undef NULL -#endif - -#include - -main (argc, argv) - int argc; - char **argv; -{ - char *term; - char *buf; - - term = argv[1]; - printf ("TERM: %s\n", term); - - buf = (char *) tgetent (0, term); - if ((int) buf <= 0) - { - printf ("No entry.\n"); - return 0; - } - - printf ("Entry: %s\n", buf); - - tprint ("cm"); - tprint ("AL"); - - printf ("co: %d\n", tgetnum ("co")); - printf ("am: %d\n", tgetflag ("am")); -} - -tprint (cap) - char *cap; -{ - char *x = tgetstr (cap, 0); - register char *y; - - printf ("%s: ", cap); - if (x) - { - for (y = x; *y; y++) - if (*y <= ' ' || *y == 0177) - printf ("\\%0o", *y); - else - putchar (*y); - free (x); - } - else - printf ("none"); - putchar ('\n'); -} - -#endif /* TEST */ diff --git a/src/libs/termcap/termcap.h b/src/libs/termcap/termcap.h deleted file mode 100644 index b19fb0a17b..0000000000 --- a/src/libs/termcap/termcap.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Declarations for termcap library. - Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _TERMCAP_H -#define _TERMCAP_H 1 - -#if __STDC__ - -extern int tgetent (char *buffer, const char *termtype); - -extern int tgetnum (const char *name); -extern int tgetflag (const char *name); -extern char *tgetstr (const char *name, char **area); - -extern char PC; -extern short ospeed; -extern void tputs (const char *string, int nlines, int (*outfun) (int)); - -extern char *tparam (const char *ctlstring, char *buffer, int size, ...); - -extern char *UP; -extern char *BC; - -extern char *tgoto (const char *cstring, int hpos, int vpos); - -#else /* not __STDC__ */ - -extern int tgetent (); - -extern int tgetnum (); -extern int tgetflag (); -extern char *tgetstr (); - -extern char PC; -extern short ospeed; - -extern void tputs (); - -extern char *tparam (); - -extern char *UP; -extern char *BC; - -extern char *tgoto (); - -#endif /* not __STDC__ */ - -#endif /* not _TERMCAP_H */ diff --git a/src/libs/termcap/termcap.info b/src/libs/termcap/termcap.info deleted file mode 100644 index f663195a33..0000000000 --- a/src/libs/termcap/termcap.info +++ /dev/null @@ -1,80 +0,0 @@ -This is Info file ./termcap.info, produced by Makeinfo-1.55 from the -input file ./termcap.texi. - - This file documents the termcap library of the GNU system. - - Copyright (C) 1988 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be stated in a -translation approved by the Foundation. - - -Indirect: -termcap.info-1: 874 -termcap.info-2: 47411 -termcap.info-3: 90390 -termcap.info-4: 138827 - -Tag Table: -(Indirect) -Node: Top874 -Node: Introduction4105 -Node: Library5832 -Node: Preparation6851 -Node: Find8034 -Node: Interrogate11492 -Node: Initialize16800 -Node: Padding18440 -Node: Why Pad19146 -Node: Not Enough20768 -Node: Describe Padding23336 -Node: Output Padding24826 -Node: Parameters28441 -Node: Encode Parameters30101 -Node: Using Parameters36185 -Node: tparam36780 -Node: tgoto38806 -Node: Data Base41361 -Node: Format42257 -Node: Capability Format44346 -Node: Naming47411 -Node: Inheriting51980 -Node: Changing54224 -Node: Capabilities55388 -Node: Basic58127 -Node: Screen Size62180 -Node: Cursor Motion63920 -Node: Wrapping74062 -Node: Scrolling77091 -Node: Windows82980 -Node: Clearing83714 -Node: Insdel Line85478 -Node: Insdel Char90390 -Node: Standout100375 -Node: Underlining109433 -Node: Cursor Visibility111852 -Node: Bell112600 -Node: Keypad113149 -Node: Meta Key117864 -Node: Initialization118818 -Node: Pad Specs121369 -Node: Status Line123422 -Node: Half-Line125306 -Node: Printer126108 -Node: Summary127787 -Node: Var Index138114 -Node: Cap Index138827 -Node: Index145991 - -End Tag Table diff --git a/src/libs/termcap/termcap.info-1 b/src/libs/termcap/termcap.info-1 deleted file mode 100644 index a5b5da0bb7..0000000000 --- a/src/libs/termcap/termcap.info-1 +++ /dev/null @@ -1,1114 +0,0 @@ -This is Info file ./termcap.info, produced by Makeinfo-1.55 from the -input file ./termcap.texi. - - This file documents the termcap library of the GNU system. - - Copyright (C) 1988 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be stated in a -translation approved by the Foundation. - - -File: termcap.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) - -* Menu: - -* Introduction:: What is termcap? Why this manual? -* Library:: The termcap library functions. -* Data Base:: What terminal descriptions in `/etc/termcap' look like. -* Capabilities:: Definitions of the individual terminal capabilities: - how to write them in descriptions, and how to use - their values to do display updating. -* Summary:: Brief table of capability names and their meanings. -* Var Index:: Index of C functions and variables. -* Cap Index:: Index of termcap capabilities. -* Index:: Concept index. - - -- The Detailed Node Listing -- - -The Termcap Library - -* Preparation:: Preparing to use the termcap library. -* Find:: Finding the description of the terminal being used. -* Interrogate:: Interrogating the description for particular capabilities. -* Initialize:: Initialization for output using termcap. -* Padding:: Outputting padding. -* Parameters:: Encoding parameters such as cursor positions. - -Padding - -* Why Pad:: Explanation of padding. -* Not Enough:: When there is not enough padding. -* Describe Padding:: The data base says how much padding a terminal needs. -* Output Padding:: Using `tputs' to output the needed padding. - -Filling In Parameters - -* Encode Parameters:: The language for encoding parameters. -* Using Parameters:: Outputting a string command with parameters. - -Sending Display Commands with Parameters - -* tparam:: The general case, for GNU termcap only. -* tgoto:: The special case of cursor motion. - -The Format of the Data Base - -* Format:: Overall format of a terminal description. -* Capability Format:: Format of capabilities within a description. -* Naming:: Naming conventions for terminal types. -* Inheriting:: Inheriting part of a description from -a related terminal type. -* Changing:: When changes in the data base take effect. - -Definitions of the Terminal Capabilities - -* Basic:: Basic characteristics. -* Screen Size:: Screen size, and what happens when it changes. -* Cursor Motion:: Various ways to move the cursor. -* Wrapping:: What happens if you write a character in the last column. -* Scrolling:: Pushing text up and down on the screen. -* Windows:: Limiting the part of the window that output affects. -* Clearing:: Erasing one or many lines. -* Insdel Line:: Making new blank lines in mid-screen; deleting lines. -* Insdel Char:: Inserting and deleting characters within a line. -* Standout:: Highlighting some of the text. -* Underlining:: Underlining some of the text. -* Cursor Visibility:: Making the cursor more or less easy to spot. -* Bell:: Attracts user's attention; not localized on the screen. -* Keypad:: Recognizing when function keys or arrows are typed. -* Meta Key:: META acts like an extra shift key. -* Initialization:: Commands used to initialize or reset the terminal. -* Pad Specs:: Info for the kernel on how much padding is needed. -* Status Line:: A status line displays "background" information. -* Half-Line:: Moving by half-lines, for superscripts and subscripts. -* Printer:: Controlling auxiliary printers of display terminals. - - -File: termcap.info, Node: Introduction, Next: Library, Prev: Top, Up: Top - -Introduction -************ - - "Termcap" is a library and data base that enables programs to use -display terminals in a terminal-independent manner. It originated in -Berkeley Unix. - - The termcap data base describes the capabilities of hundreds of -different display terminals in great detail. Some examples of the -information recorded for a terminal could include how many columns wide -it is, what string to send to move the cursor to an arbitrary position -(including how to encode the row and column numbers), how to scroll the -screen up one or several lines, and how much padding is needed for such -a scrolling operation. - - The termcap library is provided for easy access this data base in -programs that want to do terminal-independent character-based display -output. - - This manual describes the GNU version of the termcap library, which -has some extensions over the Unix version. All the extensions are -identified as such, so this manual also tells you how to use the Unix -termcap. - - The GNU version of the termcap library is available free as source -code, for use in free programs, and runs on Unix and VMS systems (at -least). You can find it in the GNU Emacs distribution in the files -`termcap.c' and `tparam.c'. - - This manual was written for the GNU project, whose goal is to -develop a complete free operating system upward-compatible with Unix -for user programs. The project is approximately two thirds complete. -For more information on the GNU project, including the GNU Emacs editor -and the mostly-portable optimizing C compiler, send one dollar to - - Free Software Foundation - 675 Mass Ave - Cambridge, MA 02139 - - -File: termcap.info, Node: Library, Next: Data Base, Prev: Introduction, Up: Top - -The Termcap Library -******************* - - The termcap library is the application programmer's interface to the -termcap data base. It contains functions for the following purposes: - - * Finding the description of the user's terminal type (`tgetent'). - - * Interrogating the description for information on various topics - (`tgetnum', `tgetflag', `tgetstr'). - - * Computing and performing padding (`tputs'). - - * Encoding numeric parameters such as cursor positions into the - terminal-specific form required for display commands (`tparam', - `tgoto'). - -* Menu: - -* Preparation:: Preparing to use the termcap library. -* Find:: Finding the description of the terminal being used. -* Interrogate:: Interrogating the description for particular capabilities. -* Initialize:: Initialization for output using termcap. -* Padding:: Outputting padding. -* Parameters:: Encoding parameters such as cursor positions. - - -File: termcap.info, Node: Preparation, Next: Find, Up: Library - -Preparing to Use the Termcap Library -==================================== - - To use the termcap library in a program, you need two kinds of -preparation: - - * The compiler needs declarations of the functions and variables in - the library. - - On GNU systems, it suffices to include the header file `termcap.h' - in each source file that uses these functions and variables. - - On Unix systems, there is often no such header file. Then you must - explictly declare the variables as external. You can do likewise - for the functions, or let them be implicitly declared and cast - their values from type `int' to the appropriate type. - - We illustrate the declarations of the individual termcap library - functions with ANSI C prototypes because they show how to pass the - arguments. If you are not using the GNU C compiler, you probably - cannot use function prototypes, so omit the argument types and - names from your declarations. - - * The linker needs to search the library. Usually either - `-ltermcap' or `-ltermlib' as an argument when linking will do - this. - - -File: termcap.info, Node: Find, Next: Interrogate, Prev: Preparation, Up: Library - -Finding a Terminal Description: `tgetent' -========================================= - - An application program that is going to use termcap must first look -up the description of the terminal type in use. This is done by calling -`tgetent', whose declaration in ANSI Standard C looks like: - - int tgetent (char *BUFFER, char *TERMTYPE); - -This function finds the description and remembers it internally so that -you can interrogate it about specific terminal capabilities (*note -Interrogate::.). - - The argument TERMTYPE is a string which is the name for the type of -terminal to look up. Usually you would obtain this from the environment -variable `TERM' using `getenv ("TERM")'. - - If you are using the GNU version of termcap, you can alternatively -ask `tgetent' to allocate enough space. Pass a null pointer for -BUFFER, and `tgetent' itself allocates the storage using `malloc'. -There is no way to get the address that was allocated, and you -shouldn't try to free the storage. - - With the Unix version of termcap, you must allocate space for the -description yourself and pass the address of the space as the argument -BUFFER. There is no way you can tell how much space is needed, so the -convention is to allocate a buffer 2048 characters long and assume that -is enough. (Formerly the convention was to allocate 1024 characters and -assume that was enough. But one day, for one kind of terminal, that was -not enough.) - - No matter how the space to store the description has been obtained, -termcap records its address internally for use when you later -interrogate the description with `tgetnum', `tgetstr' or `tgetflag'. If -the buffer was allocated by termcap, it will be freed by termcap too if -you call `tgetent' again. If the buffer was provided by you, you must -make sure that its contents remain unchanged for as long as you still -plan to interrogate the description. - - The return value of `tgetent' is -1 if there is some difficulty -accessing the data base of terminal types, 0 if the data base is -accessible but the specified type is not defined in it, and some other -value otherwise. - - Here is how you might use the function `tgetent': - - #ifdef unix - static char term_buffer[2048]; - #else - #define term_buffer 0 - #endif - - init_terminal_data () - { - char *termtype = getenv ("TERM"); - int success; - - if (termtype == 0) - fatal ("Specify a terminal type with `setenv TERM '.\n"); - - success = tgetent (term_buffer, termtype); - if (success < 0) - fatal ("Could not access the termcap data base.\n"); - if (success == 0) - fatal ("Terminal type `%s' is not defined.\n", termtype); - } - -Here we assume the function `fatal' prints an error message and exits. - - If the environment variable `TERMCAP' is defined, its value is used -to override the terminal type data base. The function `tgetent' checks -the value of `TERMCAP' automatically. If the value starts with `/' -then it is taken as a file name to use as the data base file, instead -of `/etc/termcap' which is the standard data base. If the value does -not start with `/' then it is itself used as the terminal description, -provided that the terminal type TERMTYPE is among the types it claims -to apply to. *Note Data Base::, for information on the format of a -terminal description. - - -File: termcap.info, Node: Interrogate, Next: Initialize, Prev: Find, Up: Library - -Interrogating the Terminal Description -====================================== - - Each piece of information recorded in a terminal description is -called a "capability". Each defined terminal capability has a -two-letter code name and a specific meaning. For example, the number -of columns is named `co'. *Note Capabilities::, for definitions of all -the standard capability names. - - Once you have found the proper terminal description with `tgetent' -(*note Find::.), your application program must "interrogate" it for -various terminal capabilities. You must specify the two-letter code of -the capability whose value you seek. - - Capability values can be numeric, boolean (capability is either -present or absent) or strings. Any particular capability always has -the same value type; for example, `co' always has a numeric value, -while `am' (automatic wrap at margin) is always a flag, and `cm' -(cursor motion command) always has a string value. The documentation -of each capability says which type of value it has. - - There are three functions to use to get the value of a capability, -depending on the type of value the capability has. Here are their -declarations in ANSI C: - - int tgetnum (char *NAME); - int tgetflag (char *NAME); - char *tgetstr (char *NAME, char **AREA); - -`tgetnum' - Use `tgetnum' to get a capability value that is numeric. The - argument NAME is the two-letter code name of the capability. If - the capability is present, `tgetnum' returns the numeric value - (which is nonnegative). If the capability is not mentioned in the - terminal description, `tgetnum' returns -1. - -`tgetflag' - Use `tgetflag' to get a boolean value. If the capability NAME is - present in the terminal description, `tgetflag' returns 1; - otherwise, it returns 0. - -`tgetstr' - Use `tgetstr' to get a string value. It returns a pointer to a - string which is the capability value, or a null pointer if the - capability is not present in the terminal description. - - There are two ways `tgetstr' can find space to store the string - value: - - * You can ask `tgetstr' to allocate the space. Pass a null - pointer for the argument AREA, and `tgetstr' will use - `malloc' to allocate storage big enough for the value. - Termcap will never free this storage or refer to it again; you - should free it when you are finished with it. - - This method is more robust, since there is no need to guess - how much space is needed. But it is supported only by the GNU - termcap library. - - * You can provide the space. Provide for the argument AREA the - address of a pointer variable of type `char *'. Before - calling `tgetstr', initialize the variable to point at - available space. Then `tgetstr' will store the string value - in that space and will increment the pointer variable to - point after the space that has been used. You can use the - same pointer variable for many calls to `tgetstr'. - - There is no way to determine how much space is needed for a - single string, and no way for you to prevent or handle - overflow of the area you have provided. However, you can be - sure that the total size of all the string values you will - obtain from the terminal description is no greater than the - size of the description (unless you get the same capability - twice). You can determine that size with `strlen' on the - buffer you provided to `tgetent'. See below for an example. - - Providing the space yourself is the only method supported by - the Unix version of termcap. - - Note that you do not have to specify a terminal type or terminal -description for the interrogation functions. They automatically use the -description found by the most recent call to `tgetent'. - - Here is an example of interrogating a terminal description for -various capabilities, with conditionals to select between the Unix and -GNU methods of providing buffer space. - - char *tgetstr (); - - char *cl_string, *cm_string; - int height; - int width; - int auto_wrap; - - char PC; /* For tputs. */ - char *BC; /* For tgoto. */ - char *UP; - - interrogate_terminal () - { - #ifdef UNIX - /* Here we assume that an explicit term_buffer - was provided to tgetent. */ - char *buffer - = (char *) malloc (strlen (term_buffer)); - #define BUFFADDR &buffer - #else - #define BUFFADDR 0 - #endif - - char *temp; - - /* Extract information we will use. */ - cl_string = tgetstr ("cl", BUFFADDR); - cm_string = tgetstr ("cm", BUFFADDR); - auto_wrap = tgetflag ("am"); - height = tgetnum ("li"); - width = tgetnum ("co"); - - /* Extract information that termcap functions use. */ - temp = tgetstr ("pc", BUFFADDR); - PC = temp ? *temp : 0; - BC = tgetstr ("le", BUFFADDR); - UP = tgetstr ("up", BUFFADDR); - } - -*Note Padding::, for information on the variable `PC'. *Note Using -Parameters::, for information on `UP' and `BC'. - - -File: termcap.info, Node: Initialize, Next: Padding, Prev: Interrogate, Up: Library - -Initialization for Use of Termcap -================================= - - Before starting to output commands to a terminal using termcap, an -application program should do two things: - - * Initialize various global variables which termcap library output - functions refer to. These include `PC' and `ospeed' for padding - (*note Output Padding::.) and `UP' and `BC' for cursor motion - (*note tgoto::.). - - * Tell the kernel to turn off alteration and padding of - horizontal-tab characters sent to the terminal. - - To turn off output processing in Berkeley Unix you would use `ioctl' -with code `TIOCLSET' to set the bit named `LLITOUT', and clear the bits -`ANYDELAY' using `TIOCSETN'. In POSIX or System V, you must clear the -bit named `OPOST'. Refer to the system documentation for details. - - If you do not set the terminal flags properly, some older terminals -will not work. This is because their commands may contain the -characters that normally signify newline, carriage return and -horizontal tab--characters which the kernel thinks it ought to modify -before output. - - When you change the kernel's terminal flags, you must arrange to -restore them to their normal state when your program exits. This -implies that the program must catch fatal signals such as `SIGQUIT' and -`SIGINT' and restore the old terminal flags before actually terminating. - - Modern terminals' commands do not use these special characters, so -if you do not care about problems with old terminals, you can leave the -kernel's terminal flags unaltered. - - -File: termcap.info, Node: Padding, Next: Parameters, Prev: Initialize, Up: Library - -Padding -======= - - "Padding" means outputting null characters following a terminal -display command that takes a long time to execute. The terminal -description says which commands require padding and how much; the -function `tputs', described below, outputs a terminal command while -extracting from it the padding information, and then outputs the -padding that is necessary. - -* Menu: - -* Why Pad:: Explanation of padding. -* Not Enough:: When there is not enough padding. -* Describe Padding:: The data base says how much padding a terminal needs. -* Output Padding:: Using `tputs' to output the needed padding. - - -File: termcap.info, Node: Why Pad, Next: Not Enough, Up: Padding - -Why Pad, and How ----------------- - - Most types of terminal have commands that take longer to execute -than they do to send over a high-speed line. For example, clearing the -screen may take 20msec once the entire command is received. During -that time, on a 9600 bps line, the terminal could receive about 20 -additional output characters while still busy clearing the screen. -Every terminal has a certain amount of buffering capacity to remember -output characters that cannot be processed yet, but too many slow -commands in a row can cause the buffer to fill up. Then any additional -output that cannot be processed immediately will be lost. - - To avoid this problem, we normally follow each display command with -enough useless charaters (usually null characters) to fill up the time -that the display command needs to execute. This does the job if the -terminal throws away null characters without using up space in the -buffer (which most terminals do). If enough padding is used, no output -can ever be lost. The right amount of padding avoids loss of output -without slowing down operation, since the time used to transmit padding -is time that nothing else could be done. - - The number of padding characters needed for an operation depends on -the line speed. In fact, it is proportional to the line speed. A 9600 -baud line transmits about one character per msec, so the clear screen -command in the example above would need about 20 characters of padding. -At 1200 baud, however, only about 3 characters of padding are needed -to fill up 20msec. - - -File: termcap.info, Node: Not Enough, Next: Describe Padding, Prev: Why Pad, Up: Padding - -When There Is Not Enough Padding --------------------------------- - - There are several common manifestations of insufficient padding. - - * Emacs displays `I-search: ^Q-' at the bottom of the screen. - - This means that the terminal thought its buffer was getting full of - display commands, so it tried to tell the computer to stop sending - any. - - * The screen is garbled intermittently, or the details of garbling - vary when you repeat the action. (A garbled screen could be due - to a command which is simply incorrect, or to user option in the - terminal which doesn't match the assumptions of the terminal - description, but this usually leads to reproducible failure.) - - This means that the buffer did get full, and some commands were - lost. Many changeable factors can change which ones are lost. - - * Screen is garbled at high output speeds but not at low speeds. - Padding problems nearly always go away at low speeds, usually even - at 1200 baud. - - This means that a high enough speed permits commands to arrive - faster than they can be executed. - - Although any obscure command on an obscure terminal might lack -padding, in practice problems arise most often from the clearing -commands `cl' and `cd' (*note Clearing::.), the scrolling commands `sf' -and `sr' (*note Scrolling::.), and the line insert/delete commands `al' -and `dl' (*note Insdel Line::.). - - Occasionally the terminal description fails to define `sf' and some -programs will use `do' instead, so you may get a problem with `do'. If -so, first define `sf' just like `do', then add some padding to `sf'. - - The best strategy is to add a lot of padding at first, perhaps 200 -msec. This is much more than enough; in fact, it should cause a -visible slowdown. (If you don't see a slowdown, the change has not -taken effect; *note Changing::..) If this makes the problem go away, -you have found the right place to add padding; now reduce the amount -until the problem comes back, then increase it again. If the problem -remains, either it is in some other capability or it is not a matter of -padding at all. - - Keep in mind that on many terminals the correct padding for -insert/delete line or for scrolling is cursor-position dependent. If -you get problems from scrolling a large region of the screen but not -from scrolling a small part (just a few lines moving), it may mean that -fixed padding should be replaced with position-dependent padding. - - -File: termcap.info, Node: Describe Padding, Next: Output Padding, Prev: Not Enough, Up: Padding - -Specifying Padding in a Terminal Description --------------------------------------------- - - In the terminal description, the amount of padding required by each -display command is recorded as a sequence of digits at the front of the -command. These digits specify the padding time in milliseconds (msec). -They can be followed optionally by a decimal point and one more digit, -which is a number of tenths of msec. - - Sometimes the padding needed by a command depends on the cursor -position. For example, the time taken by an "insert line" command is -usually proportional to the number of lines that need to be moved down -or cleared. An asterisk (`*') following the padding time says that the -time should be multiplied by the number of screen lines affected by the -command. - - :al=1.3*\E[L: - -is used to describe the "insert line" command for a certain terminal. -The padding required is 1.3 msec per line affected. The command itself -is `ESC [ L'. - - The padding time specified in this way tells `tputs' how many pad -characters to output. *Note Output Padding::. - - Two special capability values affect padding for all commands. -These are the `pc' and `pb'. The variable `pc' specifies the character -to pad with, and `pb' the speed below which no padding is needed. The -defaults for these variables, a null character and 0, are correct for -most terminals. *Note Pad Specs::. - - -File: termcap.info, Node: Output Padding, Prev: Describe Padding, Up: Padding - -Performing Padding with `tputs' -------------------------------- - - Use the termcap function `tputs' to output a string containing an -optional padding spec of the form described above (*note Describe -Padding::.). The function `tputs' strips off and decodes the padding -spec, outputs the rest of the string, and then outputs the appropriate -padding. Here is its declaration in ANSI C: - - char PC; - short ospeed; - - int tputs (char *STRING, int NLINES, int (*OUTFUN) ()); - - Here STRING is the string (including padding spec) to be output; -NLINES is the number of lines affected by the operation, which is used -to multiply the amount of padding if the padding spec ends with a `*'. -Finally, OUTFUN is a function (such as `fputchar') that is called to -output each character. When actually called, OUTFUN should expect one -argument, a character. - - The operation of `tputs' is controlled by two global variables, -`ospeed' and `PC'. The value of `ospeed' is supposed to be the -terminal output speed, encoded as in the `ioctl' system call which gets -the speed information. This is needed to compute the number of padding -characters. The value of `PC' is the character used for padding. - - You are responsible for storing suitable values into these variables -before using `tputs'. The value stored into the `PC' variable should be -taken from the `pc' capability in the terminal description (*note Pad -Specs::.). Store zero in `PC' if there is no `pc' capability. - - The argument NLINES requires some thought. Normally, it should be -the number of lines whose contents will be cleared or moved by the -command. For cursor motion commands, or commands that do editing -within one line, use the value 1. For most commands that affect -multiple lines, such as `al' (insert a line) and `cd' (clear from the -cursor to the end of the screen), NLINES should be the screen height -minus the current vertical position (origin 0). For multiple insert -and scroll commands such as `AL' (insert multiple lines), that same -value for NLINES is correct; the number of lines being inserted is not -correct. - - If a "scroll window" feature is used to reduce the number of lines -affected by a command, the value of NLINES should take this into -account. This is because the delay time required depends on how much -work the terminal has to do, and the scroll window feature reduces the -work. *Note Scrolling::. - - Commands such as `ic' and `dc' (insert or delete characters) are -problematical because the padding needed by these commands is -proportional to the number of characters affected, which is the number -of columns from the cursor to the end of the line. It would be nice to -have a way to specify such a dependence, and there is no need for -dependence on vertical position in these commands, so it is an obvious -idea to say that for these commands NLINES should really be the number -of columns affected. However, the definition of termcap clearly says -that NLINES is always the number of lines affected, even in this case, -where it is always 1. It is not easy to change this rule now, because -too many programs and terminal descriptions have been written to follow -it. - - Because NLINES is always 1 for the `ic' and `dc' strings, there is -no reason for them to use `*', but some of them do. These should be -corrected by deleting the `*'. If, some day, such entries have -disappeared, it may be possible to change to a more useful convention -for the NLINES argument for these operations without breaking any -programs. - - -File: termcap.info, Node: Parameters, Prev: Padding, Up: Library - -Filling In Parameters -===================== - - Some terminal control strings require numeric "parameters". For -example, when you move the cursor, you need to say what horizontal and -vertical positions to move it to. The value of the terminal's `cm' -capability, which says how to move the cursor, cannot simply be a -string of characters; it must say how to express the cursor position -numbers and where to put them within the command. - - The specifications of termcap include conventions as to which -string-valued capabilities require parameters, how many parameters, and -what the parameters mean; for example, it defines the `cm' string to -take two parameters, the vertical and horizontal positions, with 0,0 -being the upper left corner. These conventions are described where the -individual commands are documented. - - Termcap also defines a language used within the capability -definition for specifying how and where to encode the parameters for -output. This language uses character sequences starting with `%'. -(This is the same idea as `printf', but the details are different.) -The language for parameter encoding is described in this section. - - A program that is doing display output calls the functions `tparam' -or `tgoto' to encode parameters according to the specifications. These -functions produce a string containing the actual commands to be output -(as well a padding spec which must be processed with `tputs'; *note -Padding::.). - -* Menu: - -* Encode Parameters:: The language for encoding parameters. -* Using Parameters:: Outputting a string command with parameters. - - -File: termcap.info, Node: Encode Parameters, Next: Using Parameters, Up: Parameters - -Describing the Encoding ------------------------ - - A terminal command string that requires parameters contains special -character sequences starting with `%' to say how to encode the -parameters. These sequences control the actions of `tparam' and -`tgoto'. - - The parameters values passed to `tparam' or `tgoto' are considered -to form a vector. A pointer into this vector determines the next -parameter to be processed. Some of the `%'-sequences encode one -parameter and advance the pointer to the next parameter. Other -`%'-sequences alter the pointer or alter the parameter values without -generating output. - - For example, the `cm' string for a standard ANSI terminal is written -as `\E[%i%d;%dH'. (`\E' stands for ESC.) `cm' by convention always -requires two parameters, the vertical and horizontal goal positions, so -this string specifies the encoding of two parameters. Here `%i' -increments the two values supplied, and each `%d' encodes one of the -values in decimal. If the cursor position values 20,58 are encoded -with this string, the result is `\E[21;59H'. - - First, here are the `%'-sequences that generate output. Except for -`%%', each of them encodes one parameter and advances the pointer to -the following parameter. - -`%%' - Output a single `%'. This is the only way to represent a literal - `%' in a terminal command with parameters. `%%' does not use up a - parameter. - -`%d' - As in `printf', output the next parameter in decimal. - -`%2' - Like `%02d' in `printf': output the next parameter in decimal, and - always use at least two digits. - -`%3' - Like `%03d' in `printf': output the next parameter in decimal, and - always use at least three digits. Note that `%4' and so on are - *not* defined. - -`%.' - Output the next parameter as a single character whose ASCII code is - the parameter value. Like `%c' in `printf'. - -`%+CHAR' - Add the next parameter to the character CHAR, and output the - resulting character. For example, `%+ ' represents 0 as a space, - 1 as `!', etc. - - The following `%'-sequences specify alteration of the parameters -(their values, or their order) rather than encoding a parameter for -output. They generate no output; they are used only for their side -effects on the parameters. Also, they do not advance the "next -parameter" pointer except as explicitly stated. Only `%i', `%r' and -`%>' are defined in standard Unix termcap. The others are GNU -extensions. - -`%i' - Increment the next two parameters. This is used for terminals that - expect cursor positions in origin 1. For example, `%i%d,%d' would - output two parameters with `1' for 0, `2' for 1, etc. - -`%r' - Interchange the next two parameters. This is used for terminals - whose cursor positioning command expects the horizontal position - first. - -`%s' - Skip the next parameter. Do not output anything. - -`%b' - Back up one parameter. The last parameter used will become once - again the next parameter to be output, and the next output command - will use it. Using `%b' more than once, you can back up any - number of parameters, and you can refer to each parameter any - number of times. - -`%>C1C2' - Conditionally increment the next parameter. Here C1 and C2 are - characters which stand for their ASCII codes as numbers. If the - next parameter is greater than the ASCII code of C1, the ASCII - code of C2 is added to it. - -`%a OP TYPE POS' - Perform arithmetic on the next parameter, do not use it up, and do - not output anything. Here OP specifies the arithmetic operation, - while TYPE and POS together specify the other operand. - - Spaces are used above to separate the operands for clarity; the - spaces don't appear in the data base, where this sequence is - exactly five characters long. - - The character OP says what kind of arithmetic operation to - perform. It can be any of these characters: - - `=' - assign a value to the next parameter, ignoring its old value. - The new value comes from the other operand. - - `+' - add the other operand to the next parameter. - - `-' - subtract the other operand from the next parameter. - - `*' - multiply the next parameter by the other operand. - - `/' - divide the next parameter by the other operand. - - The "other operand" may be another parameter's value or a constant; - the character TYPE says which. It can be: - - `p' - Use another parameter. The character POS says which - parameter to use. Subtract 64 from its ASCII code to get the - position of the desired parameter relative to this one. Thus, - the character `A' as POS means the parameter after the next - one; the character `?' means the parameter before the next - one. - - `c' - Use a constant value. The character POS specifies the value - of the constant. The 0200 bit is cleared out, so that 0200 - can be used to represent zero. - - The following `%'-sequences are special purpose hacks to compensate -for the weird designs of obscure terminals. They modify the next -parameter or the next two parameters but do not generate output and do -not use up any parameters. `%m' is a GNU extension; the others are -defined in standard Unix termcap. - -`%n' - Exclusive-or the next parameter with 0140, and likewise the - parameter after next. - -`%m' - Complement all the bits of the next parameter and the parameter - after next. - -`%B' - Encode the next parameter in BCD. It alters the value of the - parameter by adding six times the quotient of the parameter by ten. - Here is a C statement that shows how the new value is computed: - - PARM = (PARM / 10) * 16 + PARM % 10; - -`%D' - Transform the next parameter as needed by Delta Data terminals. - This involves subtracting twice the remainder of the parameter by - 16. - - PARM -= 2 * (PARM % 16); - - -File: termcap.info, Node: Using Parameters, Prev: Encode Parameters, Up: Parameters - -Sending Display Commands with Parameters ----------------------------------------- - - The termcap library functions `tparam' and `tgoto' serve as the -analog of `printf' for terminal string parameters. The newer function -`tparam' is a GNU extension, more general but missing from Unix -termcap. The original parameter-encoding function is `tgoto', which is -preferable for cursor motion. - -* Menu: - -* tparam:: The general case, for GNU termcap only. -* tgoto:: The special case of cursor motion. - - -File: termcap.info, Node: tparam, Next: tgoto, Up: Using Parameters - -`tparam' -........ - - The function `tparam' can encode display commands with any number of -parameters and allows you to specify the buffer space. It is the -preferred function for encoding parameters for all but the `cm' -capability. Its ANSI C declaration is as follows: - - char *tparam (char *CTLSTRING, char *BUFFER, int SIZE, int PARM1,...) - - The arguments are a control string CTLSTRING (the value of a terminal -capability, presumably), an output buffer BUFFER and SIZE, and any -number of integer parameters to be encoded. The effect of `tparam' is -to copy the control string into the buffer, encoding parameters -according to the `%' sequences in the control string. - - You describe the output buffer by its address, BUFFER, and its size -in bytes, SIZE. If the buffer is not big enough for the data to be -stored in it, `tparam' calls `malloc' to get a larger buffer. In -either case, `tparam' returns the address of the buffer it ultimately -uses. If the value equals BUFFER, your original buffer was used. -Otherwise, a new buffer was allocated, and you must free it after you -are done with printing the results. If you pass zero for SIZE and -BUFFER, `tparam' always allocates the space with `malloc'. - - All capabilities that require parameters also have the ability to -specify padding, so you should use `tputs' to output the string -produced by `tparam'. *Note Padding::. Here is an example. - - { - char *buf; - char buffer[40]; - - buf = tparam (command, buffer, 40, parm); - tputs (buf, 1, fputchar); - if (buf != buffer) - free (buf); - } - - If a parameter whose value is zero is encoded with `%.'-style -encoding, the result is a null character, which will confuse `tputs'. -This would be a serious problem, but luckily `%.' encoding is used only -by a few old models of terminal, and only for the `cm' capability. To -solve the problem, use `tgoto' rather than `tparam' to encode the `cm' -capability. - - -File: termcap.info, Node: tgoto, Prev: tparam, Up: Using Parameters - -`tgoto' -....... - - The special case of cursor motion is handled by `tgoto'. There are -two reasons why you might choose to use `tgoto': - - * For Unix compatibility, because Unix termcap does not have - `tparam'. - - * For the `cm' capability, since `tgoto' has a special feature to - avoid problems with null characters, tabs and newlines on certain - old terminal types that use `%.' encoding for that capability. - - Here is how `tgoto' might be declared in ANSI C: - - char *tgoto (char *CSTRING, int HPOS, int VPOS) - - There are three arguments, the terminal description's `cm' string and -the two cursor position numbers; `tgoto' computes the parametrized -string in an internal static buffer and returns the address of that -buffer. The next time you use `tgoto' the same buffer will be reused. - - Parameters encoded with `%.' encoding can generate null characters, -tabs or newlines. These might cause trouble: the null character because -`tputs' would think that was the end of the string, the tab because the -kernel or other software might expand it into spaces, and the newline -becaue the kernel might add a carriage-return, or padding characters -normally used for a newline. To prevent such problems, `tgoto' is -careful to avoid these characters. Here is how this works: if the -target cursor position value is such as to cause a problem (that is to -say, zero, nine or ten), `tgoto' increments it by one, then compensates -by appending a string to move the cursor back or up one position. - - The compensation strings to use for moving back or up are found in -global variables named `BC' and `UP'. These are actual external C -variables with upper case names; they are declared `char *'. It is up -to you to store suitable values in them, normally obtained from the -`le' and `up' terminal capabilities in the terminal description with -`tgetstr'. Alternatively, if these two variables are both zero, the -feature of avoiding nulls, tabs and newlines is turned off. - - It is safe to use `tgoto' for commands other than `cm' only if you -have stored zero in `BC' and `UP'. - - Note that `tgoto' reverses the order of its operands: the horizontal -position comes before the vertical position in the arguments to -`tgoto', even though the vertical position comes before the horizontal -in the parameters of the `cm' string. If you use `tgoto' with a -command such as `AL' that takes one parameter, you must pass the -parameter to `tgoto' as the "vertical position". - - -File: termcap.info, Node: Data Base, Next: Capabilities, Prev: Library, Up: Top - -The Format of the Data Base -*************************** - - The termcap data base of terminal descriptions is stored in the file -`/etc/termcap'. It contains terminal descriptions, blank lines, and -comments. - - A terminal description starts with one or more names for the -terminal type. The information in the description is a series of -"capability names" and values. The capability names have standard -meanings (*note Capabilities::.) and their values describe the terminal. - -* Menu: - -* Format:: Overall format of a terminal description. -* Capability Format:: Format of capabilities within a description. -* Naming:: Naming conventions for terminal types. -* Inheriting:: Inheriting part of a description from -a related terminal type. -* Changing:: When changes in the data base take effect. - - -File: termcap.info, Node: Format, Next: Capability Format, Up: Data Base - -Terminal Description Format -=========================== - - Aside from comments (lines starting with `#', which are ignored), -each nonblank line in the termcap data base is a terminal description. -A terminal description is nominally a single line, but it can be split -into multiple lines by inserting the two characters `\ newline'. This -sequence is ignored wherever it appears in a description. - - The preferred way to split the description is between capabilities: -insert the four characters `: \ newline tab' immediately before any -colon. This allows each sub-line to start with some indentation. This -works because, after the `\ newline' are ignored, the result is `: tab -:'; the first colon ends the preceding capability and the second colon -starts the next capability. If you split with `\ newline' alone, you -may not add any indentation after them. - - Here is a real example of a terminal description: - - dw|vt52|DEC vt52:\ - :cr=^M:do=^J:nl=^J:bl=^G:\ - :le=^H:bs:cd=\EJ:ce=\EK:cl=\EH\EJ:\ - :cm=\EY%+ %+ :co#80:li#24:\ - :nd=\EC:ta=^I:pt:sr=\EI:up=\EA:\ - :ku=\EA:kd=\EB:kr=\EC:kl=\ED:kb=^H: - - Each terminal description begins with several names for the terminal -type. The names are separated by `|' characters, and a colon ends the -last name. The first name should be two characters long; it exists -only for the sake of very old Unix systems and is never used in modern -systems. The last name should be a fully verbose name such as "DEC -vt52" or "Ann Arbor Ambassador with 48 lines". The other names should -include whatever the user ought to be able to specify to get this -terminal type, such as `vt52' or `aaa-48'. *Note Naming::, for -information on how to choose terminal type names. - - After the terminal type names come the terminal capabilities, -separated by colons and with a colon after the last one. Each -capability has a two-letter name, such as `cm' for "cursor motion -string" or `li' for "number of display lines". - - -File: termcap.info, Node: Capability Format, Next: Naming, Prev: Format, Up: Data Base - -Writing the Capabilities -======================== - - There are three kinds of capabilities: flags, numbers, and strings. -Each kind has its own way of being written in the description. Each -defined capability has by convention a particular kind of value; for -example, `li' always has a numeric value and `cm' always a string value. - - A flag capability is thought of as having a boolean value: the value -is true if the capability is present, false if not. When the -capability is present, just write its name between two colons. - - A numeric capability has a value which is a nonnegative number. -Write the capability name, a `#', and the number, between two colons. -For example, `...:li#48:...' is how you specify the `li' capability for -48 lines. - - A string-valued capability has a value which is a sequence of -characters. Usually these are the characters used to perform some -display operation. Write the capability name, a `=', and the -characters of the value, between two colons. For example, -`...:cm=\E[%i%d;%dH:...' is how the cursor motion command for a -standard ANSI terminal would be specified. - - Special characters in the string value can be expressed using -`\'-escape sequences as in C; in addition, `\E' stands for ESC. `^' is -also a kind of escape character; `^' followed by CHAR stands for the -control-equivalent of CHAR. Thus, `^a' stands for the character -control-a, just like `\001'. `\' and `^' themselves can be represented -as `\\' and `\^'. - - To include a colon in the string, you must write `\072'. You might -ask, "Why can't `\:' be used to represent a colon?" The reason is that -the interrogation functions do not count slashes while looking for a -capability. Even if `:ce=ab\:cd:' were interpreted as giving the `ce' -capability the value `ab:cd', it would also appear to define `cd' as a -flag. - - The string value will often contain digits at the front to specify -padding (*note Padding::.) and/or `%'-sequences within to specify how -to encode parameters (*note Parameters::.). Although these things are -not to be output literally to the terminal, they are considered part of -the value of the capability. They are special only when the string -value is processed by `tputs', `tparam' or `tgoto'. By contrast, `\' -and `^' are considered part of the syntax for specifying the characters -in the string. - - Let's look at the VT52 example again: - - dw|vt52|DEC vt52:\ - :cr=^M:do=^J:nl=^J:bl=^G:\ - :le=^H:bs:cd=\EJ:ce=\EK:cl=\EH\EJ:\ - :cm=\EY%+ %+ :co#80:li#24:\ - :nd=\EC:ta=^I:pt:sr=\EI:up=\EA:\ - :ku=\EA:kd=\EB:kr=\EC:kl=\ED:kb=^H: - - Here we see the numeric-valued capabilities `co' and `li', the flags -`bs' and `pt', and many string-valued capabilities. Most of the -strings start with ESC represented as `\E'. The rest contain control -characters represented using `^'. The meanings of the individual -capabilities are defined elsewhere (*note Capabilities::.). - diff --git a/src/libs/termcap/termcap.info-2 b/src/libs/termcap/termcap.info-2 deleted file mode 100644 index 6098d62dfb..0000000000 --- a/src/libs/termcap/termcap.info-2 +++ /dev/null @@ -1,974 +0,0 @@ -This is Info file ./termcap.info, produced by Makeinfo-1.55 from the -input file ./termcap.texi. - - This file documents the termcap library of the GNU system. - - Copyright (C) 1988 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be stated in a -translation approved by the Foundation. - - -File: termcap.info, Node: Naming, Next: Inheriting, Prev: Capability Format, Up: Data Base - -Terminal Type Name Conventions -============================== - - There are conventions for choosing names of terminal types. For one -thing, all letters should be in lower case. The terminal type for a -terminal in its most usual or most fundamental mode of operation should -not have a hyphen in it. - - If the same terminal has other modes of operation which require -different terminal descriptions, these variant descriptions are given -names made by adding suffixes with hyphens. Such alternate descriptions -are used for two reasons: - - * When the terminal has a switch that changes its behavior. Since - the computer cannot tell how the switch is set, the user must tell - the computer by choosing the appropriate terminal type name. - - For example, the VT-100 has a setup flag that controls whether the - cursor wraps at the right margin. If this flag is set to "wrap", - you must use the terminal type `vt100-am'. Otherwise you must use - `vt100-nam'. Plain `vt100' is defined as a synonym for either - `vt100-am' or `vt100-nam' depending on the preferences of the - local site. - - The standard suffix `-am' stands for "automatic margins". - - * To give the user a choice in how to use the terminal. This is done - when the terminal has a switch that the computer normally controls. - - For example, the Ann Arbor Ambassador can be configured with many - screen sizes ranging from 20 to 60 lines. Fewer lines make bigger - characters but more lines let you see more of what you are editing. - As a result, users have different preferences. Therefore, termcap - provides terminal types for many screen sizes. If you choose type - `aaa-30', the terminal will be configured to use 30 lines; if you - choose `aaa-48', 48 lines will be used, and so on. - - Here is a list of standard suffixes and their conventional meanings: - -`-w' - Short for "wide". This is a mode that gives the terminal more - columns than usual. This is normally a user option. - -`-am' - "Automatic margins". This is an alternate description for use when - the terminal's margin-wrap switch is on; it contains the `am' - flag. The implication is that normally the switch is off and the - usual description for the terminal says that the switch is off. - -`-nam' - "No automatic margins". The opposite of `-am', this names an - alternative description which lacks the `am' flag. This implies - that the terminal is normally operated with the margin-wrap switch - turned on, and the normal description of the terminal says so. - -`-na' - "No arrows". This terminal description initializes the terminal to - keep its arrow keys in local mode. This is a user option. - -`-rv' - "Reverse video". This terminal description causes text output for - normal video to appear as reverse, and text output for reverse - video to come out as normal. Often this description differs from - the usual one by interchanging the two strings which turn reverse - video on and off. - - This is a user option; you can choose either the "reverse video" - variant terminal type or the normal terminal type, and termcap will - obey. - -`-s' - "Status". Says to enable use of a status line which ordinary - output does not touch (*note Status Line::.). - - Some terminals have a special line that is used only as a status - line. For these terminals, there is no need for an `-s' variant; - the status line commands should be defined by default. On other - terminals, enabling a status line means removing one screen line - from ordinary use and reducing the effective screen height. For - these terminals, the user can choose the `-s' variant type to - request use of a status line. - -`-NLINES' - Says to operate with NLINES lines on the screen, for terminals - such as the Ambassador which provide this as an option. Normally - this is a user option; by choosing the terminal type, you control - how many lines termcap will use. - -`-NPAGESp' - Says that the terminal has NPAGES pages worth of screen memory, - for terminals where this is a hardware option. - -`-unk' - Says that description is not for direct use, but only for - reference in `tc' capabilities. Such a description is a kind of - subroutine, because it describes the common characteristics of - several variant descriptions that would use other suffixes in - place of `-unk'. - - -File: termcap.info, Node: Inheriting, Next: Changing, Prev: Naming, Up: Data Base - -Inheriting from Related Descriptions -==================================== - - When two terminal descriptions are similar, their identical parts do -not need to be given twice. Instead, one of the two can be defined in -terms of the other, using the `tc' capability. We say that one -description "refers to" the other, or "inherits from" the other. - - The `tc' capability must be the last one in the terminal description, -and its value is a string which is the name of another terminal type -which is referred to. For example, - - N9|aaa|ambassador|aaa-30|ann arbor ambassador/30 lines:\ - :ti=\E[2J\E[30;0;0;30p:\ - :te=\E[60;0;0;30p\E[30;1H\E[J:\ - :li#30:tc=aaa-unk: - -defines the terminal type `aaa-30' (also known as plain `aaa') in terms -of `aaa-unk', which defines everything about the Ambassador that is -independent of screen height. The types `aaa-36', `aaa-48' and so on -for other screen heights are likewise defined to inherit from `aaa-unk'. - - The capabilities overridden by `aaa-30' include `li', which says how -many lines there are, and `ti' and `te', which configure the terminal -to use that many lines. - - The effective terminal description for type `aaa' consists of the -text shown above followed by the text of the description of `aaa-unk'. -The `tc' capability is handled automatically by `tgetent', which finds -the description thus referenced and combines the two descriptions -(*note Find::.). Therefore, only the implementor of the terminal -descriptions needs to think about using `tc'. Users and application -programmers do not need to be concerned with it. - - Since the reference terminal description is used last, capabilities -specified in the referring description override any specifications of -the same capabilities in the reference description. - - The referring description can cancel out a capability without -specifying any new value for it by means of a special trick. Write the -capability in the referring description, with the character `@' after -the capability name, as follows: - - NZ|aaa-30-nam|ann arbor ambassador/30 lines/no automatic-margins:\ - :am@:tc=aaa-30: - - -File: termcap.info, Node: Changing, Prev: Inheriting, Up: Data Base - -When Changes in the Data Base Take Effect -========================================= - - Each application program must read the terminal description from the -data base, so a change in the data base is effective for all jobs -started after the change is made. - - The change will usually have no effect on a job that have been in -existence since before the change. The program probably read the -terminal description once, when it was started, and is continuing to -use what it read then. If the program does not have a feature for -reexamining the data base, then you will need to run it again (probably -killing the old job). - - If the description in use is coming from the `TERMCAP' environment -variable, then the data base file is effectively overridden, and -changes in it will have no effect until you change the `TERMCAP' -variable as well. For example, some users' `.login' files -automatically copy the terminal description into `TERMCAP' to speed -startup of applications. If you have done this, you will need to -change the `TERMCAP' variable to make the changed data base take effect. - - -File: termcap.info, Node: Capabilities, Next: Summary, Prev: Data Base, Up: Top - -Definitions of the Terminal Capabilities -**************************************** - - This section is divided into many subsections, each for one aspect of -use of display terminals. For writing a display program, you usually -need only check the subsections for the operations you want to use. -For writing a terminal description, you must read each subsection and -fill in the capabilities described there. - - String capabilities that are display commands may require numeric -parameters (*note Parameters::.). Most such capabilities do not use -parameters. When a capability requires parameters, this is explicitly -stated at the beginning of its definition. In simple cases, the first -or second sentence of the definition mentions all the parameters, in -the order they should be given, using a name in upper case for each -one. For example, the `rp' capability is a command that requires two -parameters; its definition begins as follows: - - String of commands to output a graphic character C, repeated N - times. - - In complex cases or when there are many parameters, they are -described explicitly. - - When a capability is described as obsolete, this means that programs -should not be written to look for it, but terminal descriptions should -still be written to provide it. - - When a capability is described as very obsolete, this means that it -should be omitted from terminal descriptions as well. - -* Menu: - -* Basic:: Basic characteristics. -* Screen Size:: Screen size, and what happens when it changes. -* Cursor Motion:: Various ways to move the cursor. -* Wrapping:: What happens if you write a character in the last column. -* Scrolling:: Pushing text up and down on the screen. -* Windows:: Limiting the part of the window that output affects. -* Clearing:: Erasing one or many lines. -* Insdel Line:: Making new blank lines in mid-screen; deleting lines. -* Insdel Char:: Inserting and deleting characters within a line. -* Standout:: Highlighting some of the text. -* Underlining:: Underlining some of the text. -* Cursor Visibility:: Making the cursor more or less easy to spot. -* Bell:: Attracts user's attention; not localized on the screen. -* Keypad:: Recognizing when function keys or arrows are typed. -* Meta Key:: META acts like an extra shift key. -* Initialization:: Commands used to initialize or reset the terminal. -* Pad Specs:: Info for the kernel on how much padding is needed. -* Status Line:: A status line displays "background" information. -* Half-Line:: Moving by half-lines, for superscripts and subscripts. -* Printer:: Controlling auxiliary printers of display terminals. - - -File: termcap.info, Node: Basic, Next: Screen Size, Up: Capabilities - -Basic Characteristics -===================== - - This section documents the capabilities that describe the basic and -nature of the terminal, and also those that are relevant to the output -of graphic characters. - -`os' - Flag whose presence means that the terminal can overstrike. This - means that outputting a graphic character does not erase whatever - was present in the same character position before. The terminals - that can overstrike include printing terminals, storage tubes (all - obsolete nowadays), and many bit-map displays. - -`eo' - Flag whose presence means that outputting a space erases a - character position even if the terminal supports overstriking. If - this flag is not present and overstriking is supported, output of - a space has no effect except to move the cursor. - - (On terminals that do not support overstriking, you can always - assume that outputting a space at a position erases whatever - character was previously displayed there.) - -`gn' - Flag whose presence means that this terminal type is a generic type - which does not really describe any particular terminal. Generic - types are intended for use as the default type assigned when the - user connects to the system, with the intention that the user - should specify what type he really has. One example of a generic - type is the type `network'. - - Since the generic type cannot say how to do anything interesting - with the terminal, termcap-using programs will always find that the - terminal is too weak to be supported if the user has failed to - specify a real terminal type in place of the generic one. The - `gn' flag directs these programs to use a different error message: - "You have not specified your real terminal type", rather than - "Your terminal is not powerful enough to be used". - -`hc' - Flag whose presence means this is a hardcopy terminal. - -`rp' - String of commands to output a graphic character C, repeated N - times. The first parameter value is the ASCII code for the desired - character, and the second parameter is the number of times to - repeat the character. Often this command requires padding - proportional to the number of times the character is repeated. - This effect can be had by using parameter arithmetic with - `%'-sequences to compute the amount of padding, then generating - the result as a number at the front of the string so that `tputs' - will treat it as padding. - -`hz' - Flag whose presence means that the ASCII character `~' cannot be - output on this terminal because it is used for display commands. - - Programs handle this flag by checking all text to be output and - replacing each `~' with some other character(s). If this is not - done, the screen will be thoroughly garbled. - - The old Hazeltine terminals that required such treatment are - probably very rare today, so you might as well not bother to - support this flag. - -`CC' - String whose presence means the terminal has a settable command - character. The value of the string is the default command - character (which is usually ESC). - - All the strings of commands in the terminal description should be - written to use the default command character. If you are writing - an application program that changes the command character, use the - `CC' capability to figure out how to translate all the display - commands to work with the new command character. - - Most programs have no reason to look at the `CC' capability. - -`xb' - Flag whose presence identifies Superbee terminals which are unable - to transmit the characters ESC and `Control-C'. Programs which - support this flag are supposed to check the input for the code - sequences sent by the F1 and F2 keys, and pretend that ESC or - `Control-C' (respectively) had been read. But this flag is - obsolete, and not worth supporting. - - -File: termcap.info, Node: Screen Size, Next: Cursor Motion, Prev: Basic, Up: Capabilities - -Screen Size -=========== - - A terminal description has two capabilities, `co' and `li', that -describe the screen size in columns and lines. But there is more to -the question of screen size than this. - - On some operating systems the "screen" is really a window and the -effective width can vary. On some of these systems, `tgetnum' uses the -actual width of the window to decide what value to return for the `co' -capability, overriding what is actually written in the terminal -description. On other systems, it is up to the application program to -check the actual window width using a system call. For example, on BSD -4.3 systems, the system call `ioctl' with code `TIOCGWINSZ' will tell -you the current screen size. - - On all window systems, termcap is powerless to advise the application -program if the user resizes the window. Application programs must deal -with this possibility in a system-dependent fashion. On some systems -the C shell handles part of the problem by detecting changes in window -size and setting the `TERMCAP' environment variable appropriately. -This takes care of application programs that are started subsequently. -It does not help application programs already running. - - On some systems, including BSD 4.3, all programs using a terminal get -a signal named `SIGWINCH' whenever the screen size changes. Programs -that use termcap should handle this signal by using `ioctl TIOCGWINSZ' -to learn the new screen size. - -`co' - Numeric value, the width of the screen in character positions. - Even hardcopy terminals normally have a `co' capability. - -`li' - Numeric value, the height of the screen in lines. - - -File: termcap.info, Node: Cursor Motion, Next: Wrapping, Prev: Screen Size, Up: Capabilities - -Cursor Motion -============= - - Termcap assumes that the terminal has a "cursor", a spot on the -screen where a visible mark is displayed, and that most display -commands take effect at the position of the cursor. It follows that -moving the cursor to a specified location is very important. - - There are many terminal capabilities for different cursor motion -operations. A terminal description should define as many as possible, -but most programs do not need to use most of them. One capability, -`cm', moves the cursor to an arbitrary place on the screen; this by -itself is sufficient for any application as long as there is no need to -support hardcopy terminals or certain old, weak displays that have only -relative motion commands. Use of other cursor motion capabilities is an -optimization, enabling the program to output fewer characters in some -common cases. - - If you plan to use the relative cursor motion commands in an -application program, you must know what the starting cursor position -is. To do this, you must keep track of the cursor position and update -the records each time anything is output to the terminal, including -graphic characters. In addition, it is necessary to know whether the -terminal wraps after writing in the rightmost column. *Note Wrapping::. - - One other motion capability needs special mention: `nw' moves the -cursor to the beginning of the following line, perhaps clearing all the -starting line after the cursor, or perhaps not clearing at all. This -capability is a least common denominator that is probably supported -even by terminals that cannot do most other things such as `cm' or `do'. -Even hardcopy terminals can support `nw'. - -`cm' - String of commands to position the cursor at line L, column C. - Both parameters are origin-zero, and are defined relative to the - screen, not relative to display memory. - - All display terminals except a few very obsolete ones support `cm', - so it is acceptable for an application program to refuse to - operate on terminals lacking `cm'. - -`ho' - String of commands to move the cursor to the upper left corner of - the screen (this position is called the "home position"). In - terminals where the upper left corner of the screen is not the - same as the beginning of display memory, this command must go to - the upper left corner of the screen, not the beginning of display - memory. - - Every display terminal supports this capability, and many - application programs refuse to operate if the `ho' capability is - missing. - -`ll' - String of commands to move the cursor to the lower left corner of - the screen. On some terminals, moving up from home position does - this, but programs should never assume that will work. Just - output the `ll' string (if it is provided); if moving to home - position and then moving up is the best way to get there, the `ll' - command will do that. - -`cr' - String of commands to move the cursor to the beginning of the line - it is on. If this capability is not specified, many programs - assume they can use the ASCII carriage return character for this. - -`le' - String of commands to move the cursor left one column. Unless the - `bw' flag capability is specified, the effect is undefined if the - cursor is at the left margin; do not use this command there. If - `bw' is present, this command may be used at the left margin, and - it wraps the cursor to the last column of the preceding line. - -`nd' - String of commands to move the cursor right one column. The - effect is undefined if the cursor is at the right margin; do not - use this command there, not even if `am' is present. - -`up' - String of commands to move the cursor vertically up one line. The - effect of sending this string when on the top line is undefined; - programs should never use it that way. - -`do' - String of commands to move the cursor vertically down one line. - The effect of sending this string when on the bottom line is - undefined; programs should never use it that way. - - Some programs do use `do' to scroll up one line if used at the - bottom line, if `sf' is not defined but `sr' is. This is only to - compensate for certain old, incorrect terminal descriptions. (In - principle this might actually lead to incorrect behavior on other - terminals, but that seems to happen rarely if ever.) But the - proper solution is that the terminal description should define - `sf' as well as `do' if the command is suitable for scrolling. - - The original idea was that this string would not contain a newline - character and therefore could be used without disabling the - kernel's usual habit of converting of newline into a - carriage-return newline sequence. But many terminal descriptions - do use newline in the `do' string, so this is not possible; a - program which sends the `do' string must disable output conversion - in the kernel (*note Initialize::.). - -`bw' - Flag whose presence says that `le' may be used in column zero to - move to the last column of the preceding line. If this flag is - not present, `le' should not be used in column zero. - -`nw' - String of commands to move the cursor to start of next line, - possibly clearing rest of line (following the cursor) before - moving. - -`DO', `UP', `LE', `RI' - Strings of commands to move the cursor N lines down vertically, up - vertically, or N columns left or right. Do not attempt to move - past any edge of the screen with these commands; the effect of - trying that is undefined. Only a few terminal descriptions provide - these commands, and most programs do not use them. - -`CM' - String of commands to position the cursor at line L, column C, - relative to display memory. Both parameters are origin-zero. - This capability is present only in terminals where there is a - difference between screen-relative and memory-relative addressing, - and not even in all such terminals. - -`ch' - String of commands to position the cursor at column C in the same - line it is on. This is a special case of `cm' in which the - vertical position is not changed. The `ch' capability is provided - only when it is faster to output than `cm' would be in this - special case. Programs should not assume most display terminals - have `ch'. - -`cv' - String of commands to position the cursor at line L in the same - column. This is a special case of `cm' in which the horizontal - position is not changed. The `cv' capability is provided only - when it is faster to output than `cm' would be in this special - case. Programs should not assume most display terminals have `cv'. - -`sc' - String of commands to make the terminal save the current cursor - position. Only the last saved position can be used. If this - capability is present, `rc' should be provided also. Most - terminals have neither. - -`rc' - String of commands to make the terminal restore the last saved - cursor position. If this capability is present, `sc' should be - provided also. Most terminals have neither. - -`ff' - String of commands to advance to the next page, for a hardcopy - terminal. - -`ta' - String of commands to move the cursor right to the next hardware - tab stop column. Missing if the terminal does not have any kind of - hardware tabs. Do not send this command if the kernel's terminal - modes say that the kernel is expanding tabs into spaces. - -`bt' - String of commands to move the cursor left to the previous hardware - tab stop column. Missing if the terminal has no such ability; many - terminals do not. Do not send this command if the kernel's - terminal modes say that the kernel is expanding tabs into spaces. - - The following obsolete capabilities should be included in terminal -descriptions when appropriate, but should not be looked at by new -programs. - -`nc' - Flag whose presence means the terminal does not support the ASCII - carriage return character as `cr'. This flag is needed because - old programs assume, when the `cr' capability is missing, that - ASCII carriage return can be used for the purpose. We use `nc' to - tell the old programs that carriage return may not be used. - - New programs should not assume any default for `cr', so they need - not look at `nc'. However, descriptions should contain `nc' - whenever they do not contain `cr'. - -`xt' - Flag whose presence means that the ASCII tab character may not be - used for cursor motion. This flag exists because old programs - assume, when the `ta' capability is missing, that ASCII tab can be - used for the purpose. We use `xt' to tell the old programs not to - use tab. - - New programs should not assume any default for `ta', so they need - not look at `xt' in connection with cursor motion. Note that `xt' - also has implications for standout mode (*note Standout::.). It - is obsolete in regard to cursor motion but not in regard to - standout. - - In fact, `xt' means that the terminal is a Teleray 1061. - -`bc' - Very obsolete alternative name for the `le' capability. - -`bs' - Flag whose presence means that the ASCII character backspace may be - used to move the cursor left. Obsolete; look at `le' instead. - -`nl' - Obsolete capability which is a string that can either be used to - move the cursor down or to scroll. The same string must scroll - when used on the bottom line and move the cursor when used on any - other line. New programs should use `do' or `sf', and ignore `nl'. - - If there is no `nl' capability, some old programs assume they can - use the newline character for this purpose. These programs follow - a bad practice, but because they exist, it is still desirable to - define the `nl' capability in a terminal description if the best - way to move down is *not* a newline. - - -File: termcap.info, Node: Wrapping, Next: Scrolling, Prev: Cursor Motion, Up: Capabilities - -Wrapping -======== - - "Wrapping" means moving the cursor from the right margin to the left -margin of the following line. Some terminals wrap automatically when a -graphic character is output in the last column, while others do not. -Most application programs that use termcap need to know whether the -terminal wraps. There are two special flag capabilities to describe -what the terminal does when a graphic character is output in the last -column. - -`am' - Flag whose presence means that writing a character in the last - column causes the cursor to wrap to the beginning of the next line. - - If `am' is not present, writing in the last column leaves the - cursor at the place where the character was written. - - Writing in the last column of the last line should be avoided on - terminals with `am', as it may or may not cause scrolling to occur - (*note Scrolling::.). Scrolling is surely not what you would - intend. - - If your program needs to check the `am' flag, then it also needs - to check the `xn' flag which indicates that wrapping happens in a - strange way. Many common terminals have the `xn' flag. - -`xn' - Flag whose presence means that the cursor wraps in a strange way. - At least two distinct kinds of strange behavior are known; the - termcap data base does not contain anything to distinguish the two. - - On Concept-100 terminals, output in the last column wraps the - cursor almost like an ordinary `am' terminal. But if the next - thing output is a newline, it is ignored. - - DEC VT-100 terminals (when the wrap switch is on) do a different - strange thing: the cursor wraps only if the next thing output is - another graphic character. In fact, the wrap occurs when the - following graphic character is received by the terminal, before the - character is placed on the screen. - - On both of these terminals, after writing in the last column a - following graphic character will be displayed in the first column - of the following line. But the effect of relative cursor motion - characters such as newline or backspace at such a time depends on - the terminal. The effect of erase or scrolling commands also - depends on the terminal. You can't assume anything about what - they will do on a terminal that has `xn'. So, to be safe, you - should never do these things at such a time on such a terminal. - - To be sure of reliable results on a terminal which has the `xn' - flag, output a `cm' absolute positioning command after writing in - the last column. Another safe thing to do is to output - carriage-return newline, which will leave the cursor at the - beginning of the following line. - -`LP' - Flag whose presence means that it is safe to write in the last - column of the last line without worrying about undesired - scrolling. `LP' indicates the DEC flavor of `xn' strangeness. - - -File: termcap.info, Node: Scrolling, Next: Windows, Prev: Wrapping, Up: Capabilities - -Scrolling -========= - - "Scrolling" means moving the contents of the screen up or down one or -more lines. Moving the contents up is "forward scrolling"; moving them -down is "reverse scrolling". - - Scrolling happens after each line of output during ordinary output -on most display terminals. But in an application program that uses -termcap for random-access output, scrolling happens only when -explicitly requested with the commands in this section. - - Some terminals have a "scroll region" feature. This lets you limit -the effect of scrolling to a specified range of lines. Lines outside -the range are unaffected when scrolling happens. The scroll region -feature is available if either `cs' or `cS' is present. - -`sf' - String of commands to scroll the screen one line up, assuming it is - output with the cursor at the beginning of the bottom line. - -`sr' - String of commands to scroll the screen one line down, assuming it - is output with the cursor at the beginning of the top line. - -`do' - A few programs will try to use `do' to do the work of `sf'. This - is not really correct--it is an attempt to compensate for the - absence of a `sf' command in some old terminal descriptions. - - Since these terminal descriptions do define `sr', perhaps at one - time the definition of `do' was different and it could be used for - scrolling as well. But it isn't desirable to combine these two - functions in one capability, since scrolling often requires more - padding than simply moving the cursor down. Defining `sf' and - `do' separately allows you to specify the padding properly. Also, - all sources agree that `do' should not be relied on to do - scrolling. - - So the best approach is to add `sf' capabilities to the - descriptions of these terminals, copying the definition of `do' if - that does scroll. - -`SF' - String of commands to scroll the screen N lines up, assuming it is - output with the cursor at the beginning of the bottom line. - -`SR' - String of commands to scroll the screen N lines down, assuming it - is output with the cursor at the beginning of the top line. - -`cs' - String of commands to set the scroll region. This command takes - two parameters, START and END, which are the line numbers - (origin-zero) of the first line to include in the scroll region - and of the last line to include in it. When a scroll region is - set, scrolling is limited to the specified range of lines; lines - outside the range are not affected by scroll commands. - - Do not try to move the cursor outside the scroll region. The - region remains set until explicitly removed. To remove the scroll - region, use another `cs' command specifying the full height of the - screen. - - The cursor position is undefined after the `cs' command is set, so - position the cursor with `cm' immediately afterward. - -`cS' - String of commands to set the scroll region using parameters in - different form. The effect is the same as if `cs' were used. - Four parameters are required: - - 1. Total number of lines on the screen. - - 2. Number of lines above desired scroll region. - - 3. Number of lines below (outside of) desired scroll region. - - 4. Total number of lines on the screen, the same as the first - parameter. - - This capability is a GNU extension that was invented to allow the - Ann Arbor Ambassador's scroll-region command to be described; it - could also be done by putting non-Unix `%'-sequences into a `cs' - string, but that would have confused Unix programs that used the - `cs' capability with the Unix termcap. Currently only GNU Emacs - uses the `cS' capability. - -`ns' - Flag which means that the terminal does not normally scroll for - ordinary sequential output. For modern terminals, this means that - outputting a newline in ordinary sequential output with the cursor - on the bottom line wraps to the top line. For some obsolete - terminals, other things may happen. - - The terminal may be able to scroll even if it does not normally do - so. If the `sf' capability is provided, it can be used for - scrolling regardless of `ns'. - -`da' - Flag whose presence means that lines scrolled up off the top of the - screen may come back if scrolling down is done subsequently. - - The `da' and `db' flags do not, strictly speaking, affect how to - scroll. But programs that scroll usually need to clear the lines - scrolled onto the screen, if these flags are present. - -`db' - Flag whose presence means that lines scrolled down off the bottom - of the screen may come back if scrolling up is done subsequently. - -`lm' - Numeric value, the number of lines of display memory that the - terminal has. A value of zero means that the terminal has more - display memory than can fit on the screen, but no fixed number of - lines. (The number of lines may depend on the amount of text in - each line.) - - Any terminal description that defines `SF' should also define `sf'; -likewise for `SR' and `sr'. However, many terminals can only scroll by -one line at a time, so it is common to find `sf' and not `SF', or `sr' -without `SR'. - - Therefore, all programs that use the scrolling facilities should be -prepared to work with `sf' in the case that `SF' is absent, and -likewise with `sr'. On the other hand, an application program that -uses only `sf' and not `SF' is acceptable, though slow on some -terminals. - - When outputting a scroll command with `tputs', the NLINES argument -should be the total number of lines in the portion of the screen being -scrolled. Very often these commands require padding proportional to -this number of lines. *Note Padding::. - - -File: termcap.info, Node: Windows, Next: Clearing, Prev: Scrolling, Up: Capabilities - -Windows -======= - - A "window", in termcap, is a rectangular portion of the screen to -which all display operations are restricted. Wrapping, clearing, -scrolling, insertion and deletion all operate as if the specified -window were all the screen there was. - -`wi' - String of commands to set the terminal output screen window. This - string requires four parameters, all origin-zero: - 1. The first line to include in the window. - - 2. The last line to include in the window. - - 3. The first column to include in the window. - - 4. The last column to include in the window. - - Most terminals do not support windows. - - -File: termcap.info, Node: Clearing, Next: Insdel Line, Prev: Windows, Up: Capabilities - -Clearing Parts of the Screen -============================ - - There are several terminal capabilities for clearing parts of the -screen to blank. All display terminals support the `cl' string, and -most display terminals support all of these capabilities. - -`cl' - String of commands to clear the entire screen and position the - cursor at the upper left corner. - -`cd' - String of commands to clear the line the cursor is on, and all the - lines below it, down to the bottom of the screen. This command - string should be used only with the cursor in column zero; their - effect is undefined if the cursor is elsewhere. - -`ce' - String of commands to clear from the cursor to the end of the - current line. - -`ec' - String of commands to clear N characters, starting with the - character that the cursor is on. This command string is expected - to leave the cursor position unchanged. The parameter N should - never be large enough to reach past the right margin; the effect - of such a large parameter would be undefined. - - Clear to end of line (`ce') is extremely important in programs that -maintain an updating display. Nearly all display terminals support this -operation, so it is acceptable for a an application program to refuse to -work if `ce' is not present. However, if you do not want this -limitation, you can accomplish clearing to end of line by outputting -spaces until you reach the right margin. In order to do this, you must -know the current horizontal position. Also, this technique assumes -that writing a space will erase. But this happens to be true on all -the display terminals that fail to support `ce'. - - -File: termcap.info, Node: Insdel Line, Next: Insdel Char, Prev: Clearing, Up: Capabilities - -Insert/Delete Line -================== - - "Inserting a line" means creating a blank line in the middle of the -screen, and pushing the existing lines of text apart. In fact, the -lines above the insertion point do not change, while the lines below -move down, and one is normally lost at the bottom of the screen. - - "Deleting a line" means causing the line to disappear from the -screen, closing up the gap by moving the lines below it upward. A new -line appears at the bottom of the screen. Usually this line is blank, -but on terminals with the `db' flag it may be a line previously moved -off the screen bottom by scrolling or line insertion. - - Insertion and deletion of lines is useful in programs that maintain -an updating display some parts of which may get longer or shorter. -They are also useful in editors for scrolling parts of the screen, and -for redisplaying after lines of text are killed or inserted. - - Many terminals provide commands to insert or delete a single line at -the cursor position. Some provide the ability to insert or delete -several lines with one command, using the number of lines to insert or -delete as a parameter. Always move the cursor to column zero before -using any of these commands. - -`al' - String of commands to insert a blank line before the line the - cursor is on. The existing line, and all lines below it, are - moved down. The last line in the screen (or in the scroll region, - if one is set) disappears and in most circumstances is discarded. - It may not be discarded if the `db' is present (*note - Scrolling::.). - - The cursor must be at the left margin before this command is used. - This command does not move the cursor. - -`dl' - String of commands to delete the line the cursor is on. The - following lines move up, and a blank line appears at the bottom of - the screen (or bottom of the scroll region). If the terminal has - the `db' flag, a nonblank line previously pushed off the screen - bottom may reappear at the bottom. - - The cursor must be at the left margin before this command is used. - This command does not move the cursor. - -`AL' - String of commands to insert N blank lines before the line that - the cursor is on. It is like `al' repeated N times, except that - it is as fast as one `al'. - -`DL' - String of commands to delete N lines starting with the line that - the cursor is on. It is like `dl' repeated N times, except that - it is as fast as one `dl'. - - Any terminal description that defines `AL' should also define `al'; -likewise for `DL' and `dl'. However, many terminals can only insert or -delete one line at a time, so it is common to find `al' and not `AL', -or `dl' without `DL'. - - Therefore, all programs that use the insert and delete facilities -should be prepared to work with `al' in the case that `AL' is absent, -and likewise with `dl'. On the other hand, it is acceptable to write -an application that uses only `al' and `dl' and does not look for `AL' -or `DL' at all. - - If a terminal does not support line insertion and deletion directly, -but does support a scroll region, the effect of insertion and deletion -can be obtained with scrolling. However, it is up to the individual -user program to check for this possibility and use the scrolling -commands to get the desired result. It is fairly important to implement -this alternate strategy, since it is the only way to get the effect of -line insertion and deletion on the popular VT100 terminal. - - Insertion and deletion of lines is affected by the scroll region on -terminals that have a settable scroll region. This is useful when it is -desirable to move any few consecutive lines up or down by a few lines. -*Note Scrolling::. - - The line pushed off the bottom of the screen is not lost if the -terminal has the `db' flag capability; instead, it is pushed into -display memory that does not appear on the screen. This is the same -thing that happens when scrolling pushes a line off the bottom of the -screen. Either reverse scrolling or deletion of a line can bring the -apparently lost line back onto the bottom of the screen. If the -terminal has the scroll region feature as well as `db', the pushed-out -line really is lost if a scroll region is in effect. - - When outputting an insert or delete command with `tputs', the NLINES -argument should be the total number of lines from the cursor to the -bottom of the screen (or scroll region). Very often these commands -require padding proportional to this number of lines. *Note Padding::. - - For `AL' and `DL' the NLINES argument should *not* depend on the -number of lines inserted or deleted; only the total number of lines -affected. This is because it is just as fast to insert two or N lines -with `AL' as to insert one line with `al'. - diff --git a/src/libs/termcap/termcap.info-3 b/src/libs/termcap/termcap.info-3 deleted file mode 100644 index d5b309f21a..0000000000 --- a/src/libs/termcap/termcap.info-3 +++ /dev/null @@ -1,1480 +0,0 @@ -This is Info file ./termcap.info, produced by Makeinfo-1.55 from the -input file ./termcap.texi. - - This file documents the termcap library of the GNU system. - - Copyright (C) 1988 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be stated in a -translation approved by the Foundation. - - -File: termcap.info, Node: Insdel Char, Next: Standout, Prev: Insdel Line, Up: Capabilities - -Insert/Delete Character -======================= - - "Inserting a character" means creating a blank space in the middle -of a line, and pushing the rest of the line rightward. The character -in the rightmost column is lost. - - "Deleting a character" means causing the character to disappear from -the screen, closing up the gap by moving the rest of the line leftward. -A blank space appears in the rightmost column. - - Insertion and deletion of characters is useful in programs that -maintain an updating display some parts of which may get longer or -shorter. It is also useful in editors for redisplaying the results of -editing within a line. - - Many terminals provide commands to insert or delete a single -character at the cursor position. Some provide the ability to insert -or delete several characters with one command, using the number of -characters to insert or delete as a parameter. - - Many terminals provide an insert mode in which outputting a graphic -character has the added effect of inserting a position for that -character. A special command string is used to enter insert mode and -another is used to exit it. The reason for designing a terminal with -an insert mode rather than an insert command is that inserting -character positions is usually followed by writing characters into -them. With insert mode, this is as fast as simply writing the -characters, except for the fixed overhead of entering and leaving -insert mode. However, when the line speed is great enough, padding may -be required for the graphic characters output in insert mode. - - Some terminals require you to enter insert mode and then output a -special command for each position to be inserted. Or they may require -special commands to be output before or after each graphic character to -be inserted. - - Deletion of characters is usually accomplished by a straightforward -command to delete one or several positions; but on some terminals, it -is necessary to enter a special delete mode before using the delete -command, and leave delete mode afterward. Sometimes delete mode and -insert mode are the same mode. - - Some terminals make a distinction between character positions in -which a space character has been output and positions which have been -cleared. On these terminals, the effect of insert or delete character -runs to the first cleared position rather than to the end of the line. -In fact, the effect may run to more than one line if there is no -cleared position to stop the shift on the first line. These terminals -are identified by the `in' flag capability. - - On terminals with the `in' flag, the technique of skipping over -characters that you know were cleared, and then outputting text later -on in the same line, causes later insert and delete character -operations on that line to do nonstandard things. A program that has -any chance of doing this must check for the `in' flag and must be -careful to write explicit space characters into the intermediate -columns when `in' is present. - - A plethora of terminal capabilities are needed to describe all of -this complexity. Here is a list of them all. Following the list, we -present an algorithm for programs to use to take proper account of all -of these capabilities. - -`im' - String of commands to enter insert mode. - - If the terminal has no special insert mode, but it can insert - characters with a special command, `im' should be defined with a - null value, because the `vi' editor assumes that insertion of a - character is impossible if `im' is not provided. - - New programs should not act like `vi'. They should pay attention - to `im' only if it is defined. - -`ei' - String of commands to leave insert mode. This capability must be - present if `im' is. - - On a few old terminals the same string is used to enter and exit - insert mode. This string turns insert mode on if it was off, and - off it it was on. You can tell these terminals because the `ei' - string equals the `im' string. If you want to support these - terminals, you must always remember accurately whether insert mode - is in effect. However, these terminals are obsolete, and it is - reasonable to refuse to support them. On all modern terminals, you - can safely output `ei' at any time to ensure that insert mode is - turned off. - -`ic' - String of commands to insert one character position at the cursor. - The cursor does not move. - - If outputting a graphic character while in insert mode is - sufficient to insert the character, then the `ic' capability - should be defined with a null value. - - If your terminal offers a choice of ways to insert--either use - insert mode or use a special command--then define `im' and do not - define `ic', since this gives the most efficient operation when - several characters are to be inserted. *Do not* define both - strings, for that means that *both* must be used each time - insertion is done. - -`ip' - String of commands to output following an inserted graphic - character in insert mode. Often it is used just for a padding - spec, when padding is needed after an inserted character (*note - Padding::.). - -`IC' - String of commands to insert N character positions at and after - the cursor. It has the same effect as repeating the `ic' string - and a space, N times. - - If `IC' is provided, application programs may use it without first - entering insert mode. - -`mi' - Flag whose presence means it is safe to move the cursor while in - insert mode and assume the terminal remains in insert mode. - -`in' - Flag whose presence means that the terminal distinguishes between - character positions in which space characters have been output and - positions which have been cleared. - - An application program can assume that the terminal can do character -insertion if *any one of* the capabilities `IC', `im', `ic' or `ip' is -provided. - - To insert N blank character positions, move the cursor to the place -to insert them and follow this algorithm: - - 1. If an `IC' string is provided, output it with parameter N and you - are finished. Otherwise (or if you don't want to bother to look - for an `IC' string) follow the remaining steps. - - 2. Output the `im' string, if there is one, unless the terminal is - already in insert mode. - - 3. Repeat steps 4 through 6, N times. - - 4. Output the `ic' string if any. - - 5. Output a space. - - 6. Output the `ip' string if any. - - 7. Output the `ei' string, eventually, to exit insert mode. There is - no need to do this right away. If the `mi' flag is present, you - can move the cursor and the cursor will remain in insert mode; - then you can do more insertion elsewhere without reentering insert - mode. - - To insert N graphic characters, position the cursor and follow this -algorithm: - - 1. If an `IC' string is provided, output it with parameter N, then - output the graphic characters, and you are finished. Otherwise - (or if you don't want to bother to look for an `IC' string) follow - the remaining steps. - - 2. Output the `im' string, if there is one, unless the terminal is - already in insert mode. - - 3. For each character to be output, repeat steps 4 through 6. - - 4. Output the `ic' string if any. - - 5. Output the next graphic character. - - 6. Output the `ip' string if any. - - 7. Output the `ei' string, eventually, to exit insert mode. There is - no need to do this right away. If the `mi' flag is present, you - can move the cursor and the cursor will remain in insert mode; - then you can do more insertion elsewhere without reentering insert - mode. - - Note that this is not the same as the original Unix termcap -specifications in one respect: it assumes that the `IC' string can be -used without entering insert mode. This is true as far as I know, and -it allows you be able to avoid entering and leaving insert mode, and -also to be able to avoid the inserted-character padding after the -characters that go into the inserted positions. - - Deletion of characters is less complicated; deleting one column is -done by outputting the `dc' string. However, there may be a delete -mode that must be entered with `dm' in order to make `dc' work. - -`dc' - String of commands to delete one character position at the cursor. - If `dc' is not present, the terminal cannot delete characters. - -`DC' - String of commands to delete N characters starting at the cursor. - It has the same effect as repeating the `dc' string N times. Any - terminal description that has `DC' also has `dc'. - -`dm' - String of commands to enter delete mode. If not present, there is - no delete mode, and `dc' can be used at any time (assuming there is - a `dc'). - -`ed' - String of commands to exit delete mode. This must be present if - `dm' is. - - To delete N character positions, position the cursor and follow these -steps: - - 1. If the `DC' string is present, output it with parameter N and you - are finished. Otherwise, follow the remaining steps. - - 2. Output the `dm' string, unless you know the terminal is already in - delete mode. - - 3. Output the `dc' string N times. - - 4. Output the `ed' string eventually. If the flag capability `mi' is - present, you can move the cursor and do more deletion without - leaving and reentering delete mode. - - As with the `IC' string, we have departed from the original termcap -specifications by assuming that `DC' works without entering delete mode -even though `dc' would not. - - If the `dm' and `im' capabilities are both present and have the same -value, it means that the terminal has one mode for both insertion and -deletion. It is useful for a program to know this, because then it can -do insertions after deletions, or vice versa, without leaving -insert/delete mode and reentering it. - - -File: termcap.info, Node: Standout, Next: Underlining, Prev: Insdel Char, Up: Capabilities - -Standout and Appearance Modes -============================= - - "Appearance modes" are modifications to the ways characters are -displayed. Typical appearance modes include reverse video, dim, bright, -blinking, underlined, invisible, and alternate character set. Each -kind of terminal supports various among these, or perhaps none. - - For each type of terminal, one appearance mode or combination of -them that looks good for highlighted text is chosen as the "standout -mode". The capabilities `so' and `se' say how to enter and leave -standout mode. Programs that use appearance modes only to highlight -some text generally use the standout mode so that they can work on as -many terminals as possible. Use of specific appearance modes other -than "underlined" and "alternate character set" is rare. - - Terminals that implement appearance modes fall into two general -classes as to how they do it. - - In some terminals, the presence or absence of any appearance mode is -recorded separately for each character position. In these terminals, -each graphic character written is given the appearance modes current at -the time it is written, and keeps those modes until it is erased or -overwritten. There are special commands to turn the appearance modes -on or off for characters to be written in the future. - - In other terminals, the change of appearance modes is represented by -a marker that belongs to a certain screen position but affects all -following screen positions until the next marker. These markers are -traditionally called "magic cookies". - - The same capabilities (`so', `se', `mb' and so on) for turning -appearance modes on and off are used for both magic-cookie terminals -and per-character terminals. On magic cookie terminals, these give the -commands to write the magic cookies. On per-character terminals, they -change the current modes that affect future output and erasure. Some -simple applications can use these commands without knowing whether or -not they work by means of cookies. - - However, a program that maintains and updates a display needs to know -whether the terminal uses magic cookies, and exactly what their effect -is. This information comes from the `sg' capability. - - The `sg' capability is a numeric capability whose presence indicates -that the terminal uses magic cookies for appearance modes. Its value is -the number of character positions that a magic cookie occupies. Usually -the cookie occupies one or more character positions on the screen, and -these character positions are displayed as blank, but in some terminals -the cookie has zero width. - - The `sg' capability describes both the magic cookie to turn standout -on and the cookie to turn it off. This makes the assumption that both -kinds of cookie have the same width on the screen. If that is not true, -the narrower cookie must be "widened" with spaces until it has the same -width as the other. - - On some magic cookie terminals, each line always starts with normal -display; in other words, the scope of a magic cookie never extends over -more than one line. But on other terminals, one magic cookie affects -all the lines below it unless explicitly canceled. Termcap does not -define any way to distinguish these two ways magic cookies can work. -To be safe, it is best to put a cookie at the beginning of each line. - - On some per-character terminals, standout mode or other appearance -modes may be canceled by moving the cursor. On others, moving the -cursor has no effect on the state of the appearance modes. The latter -class of terminals are given the flag capability `ms' ("can move in -standout"). All programs that might have occasion to move the cursor -while appearance modes are turned on must check for this flag; if it is -not present, they should reset appearance modes to normal before doing -cursor motion. - - A program that has turned on only standout mode should use `se' to -reset the standout mode to normal. A program that has turned on only -alternate character set mode should use `ae' to return it to normal. -If it is possible that any other appearance modes are turned on, use the -`me' capability to return them to normal. - - Note that the commands to turn on one appearance mode, including `so' -and `mb' ... `mr', if used while some other appearance modes are turned -on, may combine the two modes on some terminals but may turn off the -mode previously enabled on other terminals. This is because some -terminals do not have a command to set or clear one appearance mode -without changing the others. Programs should not attempt to use -appearance modes in combination except with `sa', and when switching -from one single mode to another should always turn off the previously -enabled mode and then turn on the new desired mode. - - On some old terminals, the `so' and `se' commands may be the same -command, which has the effect of turning standout on if it is off, or -off it is on. It is therefore risky for a program to output extra `se' -commands for good measure. Fortunately, all these terminals are -obsolete. - - Programs that update displays in which standout-text may be replaced -with non-standout text must check for the `xs' flag. In a per-character -terminal, this flag says that the only way to remove standout once -written is to clear that portion of the line with the `ce' string or -something even more powerful (*note Clearing::.); just writing new -characters at those screen positions will not change the modes in -effect there. In a magic cookie terminal, `xs' says that the only way -to remove a cookie is to clear a portion of the line that includes the -cookie; writing a different cookie at the same position does not work. - - Such programs must also check for the `xt' flag, which means that the -terminal is a Teleray 1061. On this terminal it is impossible to -position the cursor at the front of a magic cookie, so the only two -ways to remove a cookie are (1) to delete the line it is on or (2) to -position the cursor at least one character before it (possibly on a -previous line) and output the `se' string, which on these terminals -finds and removes the next `so' magic cookie on the screen. (It may -also be possible to remove a cookie which is not at the beginning of a -line by clearing that line.) The `xt' capability also has implications -for the use of tab characters, but in that regard it is obsolete (*Note -Cursor Motion::). - -`so' - String of commands to enter standout mode. - -`se' - String of commands to leave standout mode. - -`sg' - Numeric capability, the width on the screen of the magic cookie. - This capability is absent in terminals that record appearance modes - character by character. - -`ms' - Flag whose presence means that it is safe to move the cursor while - the appearance modes are not in the normal state. If this flag is - absent, programs should always reset the appearance modes to - normal before moving the cursor. - -`xs' - Flag whose presence means that the only way to reset appearance - modes already on the screen is to clear to end of line. On a - per-character terminal, you must clear the area where the modes - are set. On a magic cookie terminal, you must clear an area - containing the cookie. See the discussion above. - -`xt' - Flag whose presence means that the cursor cannot be positioned - right in front of a magic cookie, and that `se' is a command to - delete the next magic cookie following the cursor. See discussion - above. - -`mb' - String of commands to enter blinking mode. - -`md' - String of commands to enter double-bright mode. - -`mh' - String of commands to enter half-bright mode. - -`mk' - String of commands to enter invisible mode. - -`mp' - String of commands to enter protected mode. - -`mr' - String of commands to enter reverse-video mode. - -`me' - String of commands to turn off all appearance modes, including - standout mode and underline mode. On some terminals it also turns - off alternate character set mode; on others, it may not. This - capability must be present if any of `mb' ... `mr' is present. - -`as' - String of commands to turn on alternate character set mode. This - mode assigns some or all graphic characters an alternate picture - on the screen. There is no standard as to what the alternate - pictures look like. - -`ae' - String of commands to turn off alternate character set mode. - -`sa' - String of commands to turn on an arbitrary combination of - appearance modes. It accepts 9 parameters, each of which controls - a particular kind of appearance mode. A parameter should be 1 to - turn its appearance mode on, or zero to turn that mode off. Most - terminals do not support the `sa' capability, even among those - that do have various appearance modes. - - The nine parameters are, in order, STANDOUT, UNDERLINE, REVERSE, - BLINK, HALF-BRIGHT, DOUBLE-BRIGHT, BLANK, PROTECT, ALT CHAR SET. - - -File: termcap.info, Node: Underlining, Next: Cursor Visibility, Prev: Standout, Up: Capabilities - -Underlining -=========== - - Underlining on most terminals is a kind of appearance mode, much like -standout mode. Therefore, it may be implemented using magic cookies or -as a flag in the terminal whose current state affects each character -that is output. *Note Standout::, for a full explanation. - - The `ug' capability is a numeric capability whose presence indicates -that the terminal uses magic cookies for underlining. Its value is the -number of character positions that a magic cookie for underlining -occupies; it is used for underlining just as `sg' is used for standout. -Aside from the simplest applications, it is impossible to use -underlining correctly without paying attention to the value of `ug'. - -`us' - String of commands to turn on underline mode or to output a magic - cookie to start underlining. - -`ue' - String of commands to turn off underline mode or to output a magic - cookie to stop underlining. - -`ug' - Width of magic cookie that represents a change of underline mode; - or missing, if the terminal does not use a magic cookie for this. - -`ms' - Flag whose presence means that it is safe to move the cursor while - the appearance modes are not in the normal state. Underlining is - an appearance mode. If this flag is absent, programs should - always turn off underlining before moving the cursor. - - There are two other, older ways of doing underlining: there can be a -command to underline a single character, or the output of `_', the -ASCII underscore character, as an overstrike could cause a character to -be underlined. New programs need not bother to handle these -capabilities unless the author cares strongly about the obscure -terminals which support them. However, terminal descriptions should -provide these capabilities when appropriate. - -`uc' - String of commands to underline the character under the cursor, and - move the cursor right. - -`ul' - Flag whose presence means that the terminal can underline by - overstriking an underscore character (`_'); some terminals can do - this even though they do not support overstriking in general. An - implication of this flag is that when outputting new text to - overwrite old text, underscore characters must be treated - specially lest they underline the old text instead. - - -File: termcap.info, Node: Cursor Visibility, Next: Bell, Prev: Underlining, Up: Capabilities - -Cursor Visibility -================= - - Some terminals have the ability to make the cursor invisible, or to -enhance it. Enhancing the cursor is often done by programs that plan -to use the cursor to indicate to the user a position of interest that -may be anywhere on the screen--for example, the Emacs editor enhances -the cursor on entry. Such programs should always restore the cursor to -normal on exit. - -`vs' - String of commands to enhance the cursor. - -`vi' - String of commands to make the cursor invisible. - -`ve' - String of commands to return the cursor to normal. - - If you define either `vs' or `vi', you must also define `ve'. - - -File: termcap.info, Node: Bell, Next: Keypad, Prev: Cursor Visibility, Up: Capabilities - -Bell -==== - - Here we describe commands to make the terminal ask for the user to -pay attention to it. - -`bl' - String of commands to cause the terminal to make an audible sound. - If this capability is absent, the terminal has no way to make a - suitable sound. - -`vb' - String of commands to cause the screen to flash to attract - attention ("visible bell"). If this capability is absent, the - terminal has no way to do such a thing. - - -File: termcap.info, Node: Keypad, Next: Meta Key, Prev: Bell, Up: Capabilities - -Keypad and Function Keys -======================== - - Many terminals have arrow and function keys that transmit specific -character sequences to the computer. Since the precise sequences used -depend on the terminal, termcap defines capabilities used to say what -the sequences are. Unlike most termcap string-valued capabilities, -these are not strings of commands to be sent to the terminal, rather -strings that are received from the terminal. - - Programs that expect to use keypad keys should check, initially, for -a `ks' capability and send it, to make the keypad actually transmit. -Such programs should also send the `ke' string when exiting. - -`ks' - String of commands to make the keypad keys transmit. If this - capability is not provided, but the others in this section are, - programs may assume that the keypad keys always transmit. - -`ke' - String of commands to make the keypad keys work locally. This - capability is provided only if `ks' is. - -`kl' - String of input characters sent by typing the left-arrow key. If - this capability is missing, you cannot expect the terminal to have - a left-arrow key that transmits anything to the computer. - -`kr' - String of input characters sent by typing the right-arrow key. - -`ku' - String of input characters sent by typing the up-arrow key. - -`kd' - String of input characters sent by typing the down-arrow key. - -`kh' - String of input characters sent by typing the "home-position" key. - -`K1' ... `K5' - Strings of input characters sent by the five other keys in a 3-by-3 - array that includes the arrow keys, if the keyboard has such a - 3-by-3 array. Note that one of these keys may be the - "home-position" key, in which case one of these capabilities will - have the same value as the `kh' key. - -`k0' - String of input characters sent by function key 10 (or 0, if the - terminal has one labeled 0). - -`k1' ... `k9' - Strings of input characters sent by function keys 1 through 9, - provided for those function keys that exist. - -`kn' - Number: the number of numbered function keys, if there are more - than 10. - -`l0' ... `l9' - Strings which are the labels appearing on the keyboard on the keys - described by the capabilities `k0' ... `l9'. These capabilities - should be left undefined if the labels are `f0' or `f10' and `f1' - ... `f9'. - -`kH' - String of input characters sent by the "home down" key, if there is - one. - -`kb' - String of input characters sent by the "backspace" key, if there is - one. - -`ka' - String of input characters sent by the "clear all tabs" key, if - there is one. - -`kt' - String of input characters sent by the "clear tab stop this column" - key, if there is one. - -`kC' - String of input characters sent by the "clear screen" key, if - there is one. - -`kD' - String of input characters sent by the "delete character" key, if - there is one. - -`kL' - String of input characters sent by the "delete line" key, if there - is one. - -`kM' - String of input characters sent by the "exit insert mode" key, if - there is one. - -`kE' - String of input characters sent by the "clear to end of line" key, - if there is one. - -`kS' - String of input characters sent by the "clear to end of screen" - key, if there is one. - -`kI' - String of input characters sent by the "insert character" or "enter - insert mode" key, if there is one. - -`kA' - String of input characters sent by the "insert line" key, if there - is one. - -`kN' - String of input characters sent by the "next page" key, if there is - one. - -`kP' - String of input characters sent by the "previous page" key, if - there is one. - -`kF' - String of input characters sent by the "scroll forward" key, if - there is one. - -`kR' - String of input characters sent by the "scroll reverse" key, if - there is one. - -`kT' - String of input characters sent by the "set tab stop in this - column" key, if there is one. - -`ko' - String listing the other function keys the terminal has. This is a - very obsolete way of describing the same information found in the - `kH' ... `kT' keys. The string contains a list of two-character - termcap capability names, separated by commas. The meaning is - that for each capability name listed, the terminal has a key which - sends the string which is the value of that capability. For - example, the value `:ko=cl,ll,sf,sr:' says that the terminal has - four function keys which mean "clear screen", "home down", "scroll - forward" and "scroll reverse". - - -File: termcap.info, Node: Meta Key, Next: Initialization, Prev: Keypad, Up: Capabilities - -Meta Key -======== - - A Meta key is a key on the keyboard that modifies each character you -type by controlling the 0200 bit. This bit is on if and only if the -Meta key is held down when the character is typed. Characters typed -using the Meta key are called Meta characters. Emacs uses Meta -characters as editing commands. - -`km' - Flag whose presence means that the terminal has a Meta key. - -`mm' - String of commands to enable the functioning of the Meta key. - -`mo' - String of commands to disable the functioning of the Meta key. - - If the terminal has `km' but does not have `mm' and `mo', it means -that the Meta key always functions. If it has `mm' and `mo', it means -that the Meta key can be turned on or off. Send the `mm' string to -turn it on, and the `mo' string to turn it off. I do not know why one -would ever not want it to be on. - - -File: termcap.info, Node: Initialization, Next: Pad Specs, Prev: Meta Key, Up: Capabilities - -Initialization -============== - -`ti' - String of commands to put the terminal into whatever special modes - are needed or appropriate for programs that move the cursor - nonsequentially around the screen. Programs that use termcap to do - full-screen display should output this string when they start up. - -`te' - String of commands to undo what is done by the `ti' string. - Programs that output the `ti' string on entry should output this - string when they exit. - -`is' - String of commands to initialize the terminal for each login - session. - -`if' - String which is the name of a file containing the string of - commands to initialize the terminal for each session of use. - Normally `is' and `if' are not both used. - -`i1' -`i3' - Two more strings of commands to initialize the terminal for each - login session. The `i1' string (if defined) is output before `is' - or `if', and the `i3' string (if defined) is output after. - - The reason for having three separate initialization strings is to - make it easier to define a group of related terminal types with - slightly different initializations. Define two or three of the - strings in the basic type; then the other types can override one - or two of the strings. - -`rs' - String of commands to reset the terminal from any strange mode it - may be in. Normally this includes the `is' string (or other - commands with the same effects) and more. What would go in the - `rs' string but not in the `is' string are annoying or slow - commands to bring the terminal back from strange modes that nobody - would normally use. - -`it' - Numeric value, the initial spacing between hardware tab stop - columns when the terminal is powered up. Programs to initialize - the terminal can use this to decide whether there is a need to set - the tab stops. If the initial width is 8, well and good; if it is - not 8, then the tab stops should be set; if they cannot be set, - the kernel is told to convert tabs to spaces, and other programs - will observe this and do likewise. - -`ct' - String of commands to clear all tab stops. - -`st' - String of commands to set tab stop at current cursor column on all - lines. - -`NF' - Flag whose presence means that the terminal does not support - XON/XOFF flow control. Programs should not send XON (`C-q') or - XOFF (`C-s') characters to the terminal. - - -File: termcap.info, Node: Pad Specs, Next: Status Line, Prev: Initialization, Up: Capabilities - -Padding Capabilities -==================== - - There are two terminal capabilities that exist just to explain the -proper way to obey the padding specifications in all the command string -capabilities. One, `pc', must be obeyed by all termcap-using programs. - -`pb' - Numeric value, the lowest baud rate at which padding is actually - needed. Programs may check this and refrain from doing any - padding at lower speeds. - -`pc' - String of commands for padding. The first character of this - string is to be used as the pad character, instead of using null - characters for padding. If `pc' is not provided, use null - characters. Every program that uses termcap must look up this - capability and use it to set the variable `PC' that is used by - `tputs'. *Note Padding::. - - Some termcap capabilities exist just to specify the amount of -padding that the kernel should give to cursor motion commands used in -ordinary sequential output. - -`dC' - Numeric value, the number of msec of padding needed for the - carriage-return character. - -`dN' - Numeric value, the number of msec of padding needed for the newline - (linefeed) character. - -`dB' - Numeric value, the number of msec of padding needed for the - backspace character. - -`dF' - Numeric value, the number of msec of padding needed for the - formfeed character. - -`dT' - Numeric value, the number of msec of padding needed for the tab - character. - - In some systems, the kernel uses the above capabilities; in other -systems, the kernel uses the paddings specified in the string -capabilities `cr', `sf', `le', `ff' and `ta'. Descriptions of -terminals which require such padding should contain the `dC' ... `dT' -capabilities and also specify the appropriate padding in the -corresponding string capabilities. Since no modern terminals require -padding for ordinary sequential output, you probably won't need to do -either of these things. - - -File: termcap.info, Node: Status Line, Next: Half-Line, Prev: Pad Specs, Up: Capabilities - -Status Line -=========== - - A "status line" is a line on the terminal that is not used for -ordinary display output but instead used for a special message. The -intended use is for a continuously updated description of what the -user's program is doing, and that is where the name "status line" comes -from, but in fact it could be used for anything. The distinguishing -characteristic of a status line is that ordinary output to the terminal -does not affect it; it changes only if the special status line commands -of this section are used. - -`hs' - Flag whose presence means that the terminal has a status line. If - a terminal description specifies that there is a status line, it - must provide the `ts' and `fs' capabilities. - -`ts' - String of commands to move the terminal cursor into the status - line. Usually these commands must specifically record the old - cursor position for the sake of the `fs' string. - -`fs' - String of commands to move the cursor back from the status line to - its previous position (outside the status line). - -`es' - Flag whose presence means that other display commands work while - writing the status line. In other words, one can clear parts of - it, insert or delete characters, move the cursor within it using - `ch' if there is a `ch' capability, enter and leave standout mode, - and so on. - -`ds' - String of commands to disable the display of the status line. This - may be absent, if there is no way to disable the status line - display. - -`ws' - Numeric value, the width of the status line. If this capability is - absent in a terminal that has a status line, it means the status - line is the same width as the other lines. - - Note that the value of `ws' is sometimes as small as 8. - - -File: termcap.info, Node: Half-Line, Next: Printer, Prev: Status Line, Up: Capabilities - -Half-Line Motion -================ - - Some terminals have commands for moving the cursor vertically by -half-lines, useful for outputting subscripts and superscripts. Mostly -it is hardcopy terminals that have such features. - -`hu' - String of commands to move the cursor up half a line. If the - terminal is a display, it is your responsibility to avoid moving - up past the top line; however, most likely the terminal that - supports this is a hardcopy terminal and there is nothing to be - concerned about. - -`hd' - String of commands to move the cursor down half a line. If the - terminal is a display, it is your responsibility to avoid moving - down past the bottom line, etc. - - -File: termcap.info, Node: Printer, Prev: Half-Line, Up: Capabilities - -Controlling Printers Attached to Terminals -========================================== - - Some terminals have attached hardcopy printer ports. They may be -able to copy the screen contents to the printer; they may also be able -to redirect output to the printer. Termcap does not have anything to -tell the program whether the redirected output appears also on the -screen; it does on some terminals but not all. - -`ps' - String of commands to cause the contents of the screen to be - printed. If it is absent, the screen contents cannot be printed. - -`po' - String of commands to redirect further output to the printer. - -`pf' - String of commands to terminate redirection of output to the - printer. This capability must be present in the description if - `po' is. - -`pO' - String of commands to redirect output to the printer for next N - characters of output, regardless of what they are. Redirection - will end automatically after N characters of further output. Until - then, nothing that is output can end redirection, not even the - `pf' string if there is one. The number N should not be more than - 255. - - One use of this capability is to send non-text byte sequences - (such as bit-maps) to the printer. - - Most terminals with printers do not support all of `ps', `po' and -`pO'; any one or two of them may be supported. To make a program that -can send output to all kinds of printers, it is necessary to check for -all three of these capabilities, choose the most convenient of the ones -that are provided, and use it in its own appropriate fashion. - - -File: termcap.info, Node: Summary, Next: Var Index, Prev: Capabilities, Up: Top - -Summary of Capability Names -*************************** - - Here are all the terminal capability names in alphabetical order -with a brief description of each. For cross references to their -definitions, see the index of capability names (*note Cap Index::.). - -`ae' - String to turn off alternate character set mode. - -`al' - String to insert a blank line before the cursor. - -`AL' - String to insert N blank lines before the cursor. - -`am' - Flag: output to last column wraps cursor to next line. - -`as' - String to turn on alternate character set mode.like. - -`bc' - Very obsolete alternative name for the `le' capability. - -`bl' - String to sound the bell. - -`bs' - Obsolete flag: ASCII backspace may be used for leftward motion. - -`bt' - String to move the cursor left to the previous hardware tab stop - column. - -`bw' - Flag: `le' at left margin wraps to end of previous line. - -`CC' - String to change terminal's command character. - -`cd' - String to clear the line the cursor is on, and following lines. - -`ce' - String to clear from the cursor to the end of the line. - -`ch' - String to position the cursor at column C in the same line. - -`cl' - String to clear the entire screen and put cursor at upper left - corner. - -`cm' - String to position the cursor at line L, column C. - -`CM' - String to position the cursor at line L, column C, relative to - display memory. - -`co' - Number: width of the screen. - -`cr' - String to move cursor sideways to left margin. - -`cs' - String to set the scroll region. - -`cS' - Alternate form of string to set the scroll region. - -`ct' - String to clear all tab stops. - -`cv' - String to position the cursor at line L in the same column. - -`da' - Flag: data scrolled off top of screen may be scrolled back. - -`db' - Flag: data scrolled off bottom of screen may be scrolled back. - -`dB' - Obsolete number: msec of padding needed for the backspace - character. - -`dc' - String to delete one character position at the cursor. - -`dC' - Obsolete number: msec of padding needed for the carriage-return - character. - -`DC' - String to delete N characters starting at the cursor. - -`dF' - Obsolete number: msec of padding needed for the formfeed character. - -`dl' - String to delete the line the cursor is on. - -`DL' - String to delete N lines starting with the cursor's line. - -`dm' - String to enter delete mode. - -`dN' - Obsolete number: msec of padding needed for the newline character. - -`do' - String to move the cursor vertically down one line. - -`DO' - String to move cursor vertically down N lines. - -`ds' - String to disable the display of the status line. - -`dT' - Obsolete number: msec of padding needed for the tab character. - -`ec' - String of commands to clear N characters at cursor. - -`ed' - String to exit delete mode. - -`ei' - String to leave insert mode. - -`eo' - Flag: output of a space can erase an overstrike. - -`es' - Flag: other display commands work while writing the status line. - -`ff' - String to advance to the next page, for a hardcopy terminal. - -`fs' - String to move the cursor back from the status line to its - previous position (outside the status line). - -`gn' - Flag: this terminal type is generic, not real. - -`hc' - Flag: hardcopy terminal. - -`hd' - String to move the cursor down half a line. - -`ho' - String to position cursor at upper left corner. - -`hs' - Flag: the terminal has a status line. - -`hu' - String to move the cursor up half a line. - -`hz' - Flag: terminal cannot accept `~' as output. - -`i1' - String to initialize the terminal for each login session. - -`i3' - String to initialize the terminal for each login session. - -`ic' - String to insert one character position at the cursor. - -`IC' - String to insert N character positions at the cursor. - -`if' - String naming a file of commands to initialize the terminal. - -`im' - String to enter insert mode. - -`in' - Flag: outputting a space is different from moving over empty - positions. - -`ip' - String to output following an inserted character in insert mode. - -`is' - String to initialize the terminal for each login session. - -`it' - Number: initial spacing between hardware tab stop columns. - -`k0' - String of input sent by function key 0 or 10. - -`k1 ... k9' - Strings of input sent by function keys 1 through 9. - -`K1 ... K5' - Strings sent by the five other keys in 3-by-3 array with arrows. - -`ka' - String of input sent by the "clear all tabs" key. - -`kA' - String of input sent by the "insert line" key. - -`kb' - String of input sent by the "backspace" key. - -`kC' - String of input sent by the "clear screen" key. - -`kd' - String of input sent by typing the down-arrow key. - -`kD' - String of input sent by the "delete character" key. - -`ke' - String to make the function keys work locally. - -`kE' - String of input sent by the "clear to end of line" key. - -`kF' - String of input sent by the "scroll forward" key. - -`kh' - String of input sent by typing the "home-position" key. - -`kH' - String of input sent by the "home down" key. - -`kI' - String of input sent by the "insert character" or "enter insert - mode" key. - -`kl' - String of input sent by typing the left-arrow key. - -`kL' - String of input sent by the "delete line" key. - -`km' - Flag: the terminal has a Meta key. - -`kM' - String of input sent by the "exit insert mode" key. - -`kn' - Numeric value, the number of numbered function keys. - -`kN' - String of input sent by the "next page" key. - -`ko' - Very obsolete string listing the terminal's named function keys. - -`kP' - String of input sent by the "previous page" key. - -`kr' - String of input sent by typing the right-arrow key. - -`kR' - String of input sent by the "scroll reverse" key. - -`ks' - String to make the function keys transmit. - -`kS' - String of input sent by the "clear to end of screen" key. - -`kt' - String of input sent by the "clear tab stop this column" key. - -`kT' - String of input sent by the "set tab stop in this column" key. - -`ku' - String of input sent by typing the up-arrow key. - -`l0' - String on keyboard labelling function key 0 or 10. - -`l1 ... l9' - Strings on keyboard labelling function keys 1 through 9. - -`le' - String to move the cursor left one column. - -`LE' - String to move cursor left N columns. - -`li' - Number: height of the screen. - -`ll' - String to position cursor at lower left corner. - -`lm' - Number: lines of display memory. - -`LP' - Flag: writing to last column of last line will not scroll. - -`mb' - String to enter blinking mode. - -`md' - String to enter double-bright mode. - -`me' - String to turn off all appearance modes - -`mh' - String to enter half-bright mode. - -`mi' - Flag: cursor motion in insert mode is safe. - -`mk' - String to enter invisible mode. - -`mm' - String to enable the functioning of the Meta key. - -`mo' - String to disable the functioning of the Meta key. - -`mp' - String to enter protected mode. - -`mr' - String to enter reverse-video mode. - -`ms' - Flag: cursor motion in standout mode is safe. - -`nc' - Obsolete flag: do not use ASCII carriage-return on this terminal. - -`nd' - String to move the cursor right one column. - -`NF' - Flag: do not use XON/XOFF flow control. - -`nl' - Obsolete alternative name for the `do' and `sf' capabilities. - -`ns' - Flag: the terminal does not normally scroll for sequential output. - -`nw' - String to move to start of next line, possibly clearing rest of - old line. - -`os' - Flag: terminal can overstrike. - -`pb' - Number: the lowest baud rate at which padding is actually needed. - -`pc' - String containing character for padding. - -`pf' - String to terminate redirection of output to the printer. - -`po' - String to redirect further output to the printer. - -`pO' - String to redirect N characters ofoutput to the printer. - -`ps' - String to print the screen on the attached printer. - -`rc' - String to move to last saved cursor position. - -`RI' - String to move cursor right N columns. - -`rp' - String to output character C repeated N times. - -`rs' - String to reset the terminal from any strange modes. - -`sa' - String to turn on an arbitrary combination of appearance modes. - -`sc' - String to save the current cursor position. - -`se' - String to leave standout mode. - -`sf' - String to scroll the screen one line up. - -`SF' - String to scroll the screen N lines up. - -`sg' - Number: width of magic standout cookie. Absent if magic cookies - are not used. - -`so' - String to enter standout mode. - -`sr' - String to scroll the screen one line down. - -`SR' - String to scroll the screen N line down. - -`st' - String to set tab stop at current cursor column on all lines. - programs. - -`ta' - String to move the cursor right to the next hardware tab stop - column. - -`te' - String to return terminal to settings for sequential output. - -`ti' - String to initialize terminal for random cursor motion. - -`ts' - String to move the terminal cursor into the status line. - -`uc' - String to underline one character and move cursor right. - -`ue' - String to turn off underline mode - -`ug' - Number: width of underlining magic cookie. Absent if underlining - doesn't use magic cookies. - -`ul' - Flag: underline by overstriking with an underscore. - -`up' - String to move the cursor vertically up one line. - -`UP' - String to move cursor vertically up N lines. - -`us' - String to turn on underline mode - -`vb' - String to make the screen flash. - -`ve' - String to return the cursor to normal. - -`vi' - String to make the cursor invisible. - -`vs' - String to enhance the cursor. - -`wi' - String to set the terminal output screen window. - -`ws' - Number: the width of the status line. - -`xb' - Flag: superbee terminal. - -`xn' - Flag: cursor wraps in a strange way. - -`xs' - Flag: clearing a line is the only way to clear the appearance - modes of positions in that line (or, only way to remove magic - cookies on that line). - -`xt' - Flag: Teleray 1061; several strange characteristics. - - -File: termcap.info, Node: Var Index, Next: Cap Index, Prev: Summary, Up: Top - -Variable and Function Index -*************************** - -* Menu: - -* BC: tgoto. -* ospeed: Output Padding. -* PC: Output Padding. -* tgetent: Find. -* tgetflag: Interrogate. -* tgetnum: Interrogate. -* tgetstr: Interrogate. -* tgoto: tgoto. -* tparam: tparam. -* tputs: Output Padding. -* UP: tgoto. - diff --git a/src/libs/termcap/termcap.info-4 b/src/libs/termcap/termcap.info-4 deleted file mode 100644 index 4b8bf791ce..0000000000 --- a/src/libs/termcap/termcap.info-4 +++ /dev/null @@ -1,220 +0,0 @@ -This is Info file ./termcap.info, produced by Makeinfo-1.55 from the -input file ./termcap.texi. - - This file documents the termcap library of the GNU system. - - Copyright (C) 1988 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be stated in a -translation approved by the Foundation. - - -File: termcap.info, Node: Cap Index, Next: Index, Prev: Var Index, Up: Top - -Capability Index -**************** - -* Menu: - -* ae: Standout. -* al: Insdel Line. -* AL: Insdel Line. -* am: Wrapping. -* as: Standout. -* bc: Cursor Motion. -* bl: Bell. -* bs: Cursor Motion. -* bt: Cursor Motion. -* bw: Cursor Motion. -* CC: Basic. -* cd: Clearing. -* ce: Clearing. -* ch: Cursor Motion. -* cl: Clearing. -* cm: Cursor Motion. -* CM: Cursor Motion. -* co: Screen Size. -* cr: Cursor Motion. -* cS: Scrolling. -* cs: Scrolling. -* ct: Initialization. -* cv: Cursor Motion. -* da: Scrolling. -* dB: Pad Specs. -* db: Scrolling. -* dC: Pad Specs. -* DC: Insdel Char. -* dc: Insdel Char. -* dF: Pad Specs. -* dl: Insdel Line. -* DL: Insdel Line. -* dm: Insdel Char. -* dN: Pad Specs. -* do: Cursor Motion. -* DO: Cursor Motion. -* ds: Status Line. -* dT: Pad Specs. -* ec: Clearing. -* ed: Insdel Char. -* ei: Insdel Char. -* eo: Basic. -* es: Status Line. -* ff: Cursor Motion. -* fs: Status Line. -* gn: Basic. -* hc: Basic. -* hd: Half-Line. -* ho: Cursor Motion. -* hs: Status Line. -* hu: Half-Line. -* hz: Basic. -* i1: Initialization. -* i3: Initialization. -* IC: Insdel Char. -* ic: Insdel Char. -* if: Initialization. -* im: Insdel Char. -* in: Insdel Char. -* ip: Insdel Char. -* is: Initialization. -* it: Initialization. -* K1...K5: Keypad. -* k1...k9: Keypad. -* kA...kT: Keypad. -* ka...ku: Keypad. -* km: Meta Key. -* l0...l9: Keypad. -* le: Cursor Motion. -* LE: Cursor Motion. -* li: Screen Size. -* ll: Cursor Motion. -* lm: Scrolling. -* LP: Wrapping. -* mb: Standout. -* md: Standout. -* me: Standout. -* mh: Standout. -* mi: Insdel Char. -* mk: Standout. -* mm: Meta Key. -* mo: Meta Key. -* mp: Standout. -* mr: Standout. -* ms: Standout. -* ms: Underlining. -* nc: Cursor Motion. -* nd: Cursor Motion. -* NF: Initialization. -* nl: Cursor Motion. -* ns: Scrolling. -* nw: Cursor Motion. -* os: Basic. -* pb: Pad Specs. -* pc: Pad Specs. -* pf: Printer. -* pO: Printer. -* po: Printer. -* ps: Printer. -* rc: Cursor Motion. -* RI: Cursor Motion. -* rp: Basic. -* rs: Initialization. -* sa: Standout. -* sc: Cursor Motion. -* se: Standout. -* SF: Scrolling. -* sf: Scrolling. -* sg: Standout. -* so: Standout. -* SR: Scrolling. -* sr: Scrolling. -* st: Initialization. -* ta: Cursor Motion. -* te: Initialization. -* ti: Initialization. -* ts: Status Line. -* uc: Underlining. -* ue: Underlining. -* ug: Underlining. -* ul: Underlining. -* up: Cursor Motion. -* UP: Cursor Motion. -* us: Underlining. -* vb: Bell. -* ve: Cursor Visibility. -* vi: Cursor Visibility. -* vs: Cursor Visibility. -* wi: Windows. -* ws: Status Line. -* xb: Basic. -* xn: Wrapping. -* xs: Standout. -* xt: Cursor Motion. -* xt: Standout. - - -File: termcap.info, Node: Index, Prev: Cap Index, Up: Top - -Concept Index -************* - -* Menu: - -* %: Encode Parameters. -* appearance modes: Standout. -* bell: Bell. -* clearing the screen: Clearing. -* command character: Basic. -* cursor motion: Cursor Motion. -* delete character: Insdel Char. -* delete line: Insdel Line. -* delete mode: Insdel Char. -* description format: Format. -* erasing: Clearing. -* generic terminal type: Basic. -* home position: Cursor Motion. -* inheritance: Inheriting. -* initialization: Initialization. -* insert character: Insdel Char. -* insert line: Insdel Line. -* insert mode: Insdel Char. -* line speed: Output Padding. -* magic cookie: Standout. -* meta key: Meta Key. -* names of terminal types: Naming. -* overstrike: Basic. -* padding: Pad Specs. -* padding: Padding. -* parameters: Parameters. -* printer: Printer. -* repeat output: Basic. -* reset: Initialization. -* screen size: Screen Size. -* screen size: Naming. -* screen size: Screen Size. -* scrolling: Scrolling. -* standout: Standout. -* status line: Status Line. -* Superbee: Basic. -* tab stops: Initialization. -* termcap: Introduction. -* terminal flags (kernel): Initialize. -* underlining: Underlining. -* visibility: Cursor Visibility. -* visible bell: Bell. -* window: Windows. -* wrapping: Wrapping. -* wrapping: Naming. - - diff --git a/src/libs/termcap/termcap.texi b/src/libs/termcap/termcap.texi deleted file mode 100644 index 7a6cd565bb..0000000000 --- a/src/libs/termcap/termcap.texi +++ /dev/null @@ -1,3618 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@setfilename termcap.info -@settitle The Termcap Library -@smallbook - -@ifinfo -This file documents the termcap library of the GNU system. - -Copyright (C) 1988 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. -@end ifinfo - -@setchapternewpage odd - -@c @shorttitlepage The Termcap Manual - -@titlepage -@ignore -@sp 6 -@center @titlefont{Termcap} -@sp 1 -@center The Termcap Library and Data Base -@sp 4 -@center Second Edition -@sp 1 -@center December 1992 -@sp 5 -@center Richard M. Stallman -@sp 1 -@center Free Software Foundation -@end ignore - -@c Real title page -@title The Termcap Manual -@subtitle The Termcap Library and Data Base -@subtitle Second Edition -@subtitle December 1992 -@author Richard M. Stallman -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 1988 Free Software Foundation, Inc. - -Published by the Free Software Foundation -(675 Mass Ave, Cambridge MA 02139). -Printed copies are available for $10 each. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. -@sp 2 -Cover art by Etienne Suvasa. -@end titlepage -@page - -@synindex vr fn - -@node Top, Introduction, (dir), (dir) - -@menu -* Introduction:: What is termcap? Why this manual? -* Library:: The termcap library functions. -* Data Base:: What terminal descriptions in @file{/etc/termcap} look like. -* Capabilities:: Definitions of the individual terminal capabilities: - how to write them in descriptions, and how to use - their values to do display updating. -* Summary:: Brief table of capability names and their meanings. -* Var Index:: Index of C functions and variables. -* Cap Index:: Index of termcap capabilities. -* Index:: Concept index. - - --- The Detailed Node Listing --- - -The Termcap Library - -* Preparation:: Preparing to use the termcap library. -* Find:: Finding the description of the terminal being used. -* Interrogate:: Interrogating the description for particular capabilities. -* Initialize:: Initialization for output using termcap. -* Padding:: Outputting padding. -* Parameters:: Encoding parameters such as cursor positions. - -Padding - -* Why Pad:: Explanation of padding. -* Not Enough:: When there is not enough padding. -* Describe Padding:: The data base says how much padding a terminal needs. -* Output Padding:: Using @code{tputs} to output the needed padding. - -Filling In Parameters - -* Encode Parameters:: The language for encoding parameters. -* Using Parameters:: Outputting a string command with parameters. - -Sending Display Commands with Parameters - -* tparam:: The general case, for GNU termcap only. -* tgoto:: The special case of cursor motion. - -The Format of the Data Base - -* Format:: Overall format of a terminal description. -* Capability Format:: Format of capabilities within a description. -* Naming:: Naming conventions for terminal types. -* Inheriting:: Inheriting part of a description from -a related terminal type. -* Changing:: When changes in the data base take effect. - -Definitions of the Terminal Capabilities - -* Basic:: Basic characteristics. -* Screen Size:: Screen size, and what happens when it changes. -* Cursor Motion:: Various ways to move the cursor. -* Wrapping:: What happens if you write a character in the last column. -* Scrolling:: Pushing text up and down on the screen. -* Windows:: Limiting the part of the window that output affects. -* Clearing:: Erasing one or many lines. -* Insdel Line:: Making new blank lines in mid-screen; deleting lines. -* Insdel Char:: Inserting and deleting characters within a line. -* Standout:: Highlighting some of the text. -* Underlining:: Underlining some of the text. -* Cursor Visibility:: Making the cursor more or less easy to spot. -* Bell:: Attracts user's attention; not localized on the screen. -* Keypad:: Recognizing when function keys or arrows are typed. -* Meta Key:: @key{META} acts like an extra shift key. -* Initialization:: Commands used to initialize or reset the terminal. -* Pad Specs:: Info for the kernel on how much padding is needed. -* Status Line:: A status line displays ``background'' information. -* Half-Line:: Moving by half-lines, for superscripts and subscripts. -* Printer:: Controlling auxiliary printers of display terminals. -@end menu - -@node Introduction, Library, Top, Top -@unnumbered Introduction - -@cindex termcap -@dfn{Termcap} is a library and data base that enables programs to use -display terminals in a terminal-independent manner. It originated in -Berkeley Unix. - -The termcap data base describes the capabilities of hundreds of different -display terminals in great detail. Some examples of the information -recorded for a terminal could include how many columns wide it is, what -string to send to move the cursor to an arbitrary position (including how -to encode the row and column numbers), how to scroll the screen up one or -several lines, and how much padding is needed for such a scrolling -operation. - -The termcap library is provided for easy access this data base in programs -that want to do terminal-independent character-based display output. - -This manual describes the GNU version of the termcap library, which has -some extensions over the Unix version. All the extensions are identified -as such, so this manual also tells you how to use the Unix termcap. - -The GNU version of the termcap library is available free as source code, -for use in free programs, and runs on Unix and VMS systems (at least). You -can find it in the GNU Emacs distribution in the files @file{termcap.c} and -@file{tparam.c}. - -This manual was written for the GNU project, whose goal is to develop a -complete free operating system upward-compatible with Unix for user -programs. The project is approximately two thirds complete. For more -information on the GNU project, including the GNU Emacs editor and the -mostly-portable optimizing C compiler, send one dollar to - -@display -Free Software Foundation -675 Mass Ave -Cambridge, MA 02139 -@end display - -@node Library, Data Base, Introduction, Top -@chapter The Termcap Library - -The termcap library is the application programmer's interface to the -termcap data base. It contains functions for the following purposes: - -@itemize @bullet -@item -Finding the description of the user's terminal type (@code{tgetent}). - -@item -Interrogating the description for information on various topics -(@code{tgetnum}, @code{tgetflag}, @code{tgetstr}). - -@item -Computing and performing padding (@code{tputs}). - -@item -Encoding numeric parameters such as cursor positions into the -terminal-specific form required for display commands (@code{tparam}, -@code{tgoto}). -@end itemize - -@menu -* Preparation:: Preparing to use the termcap library. -* Find:: Finding the description of the terminal being used. -* Interrogate:: Interrogating the description for particular capabilities. -* Initialize:: Initialization for output using termcap. -* Padding:: Outputting padding. -* Parameters:: Encoding parameters such as cursor positions. -@end menu - -@node Preparation, Find, , Library -@section Preparing to Use the Termcap Library - -To use the termcap library in a program, you need two kinds of preparation: - -@itemize @bullet -@item -The compiler needs declarations of the functions and variables in the -library. - -On GNU systems, it suffices to include the header file -@file{termcap.h} in each source file that uses these functions and -variables.@refill - -On Unix systems, there is often no such header file. Then you must -explictly declare the variables as external. You can do likewise for -the functions, or let them be implicitly declared and cast their -values from type @code{int} to the appropriate type. - -We illustrate the declarations of the individual termcap library -functions with ANSI C prototypes because they show how to pass the -arguments. If you are not using the GNU C compiler, you probably -cannot use function prototypes, so omit the argument types and names -from your declarations. - -@item -The linker needs to search the library. Usually either -@samp{-ltermcap} or @samp{-ltermlib} as an argument when linking will -do this.@refill -@end itemize - -@node Find, Interrogate, Preparation, Library -@section Finding a Terminal Description: @code{tgetent} - -@findex tgetent -An application program that is going to use termcap must first look up the -description of the terminal type in use. This is done by calling -@code{tgetent}, whose declaration in ANSI Standard C looks like: - -@example -int tgetent (char *@var{buffer}, char *@var{termtype}); -@end example - -@noindent -This function finds the description and remembers it internally so that -you can interrogate it about specific terminal capabilities -(@pxref{Interrogate}). - -The argument @var{termtype} is a string which is the name for the type of -terminal to look up. Usually you would obtain this from the environment -variable @code{TERM} using @code{getenv ("TERM")}. - -If you are using the GNU version of termcap, you can alternatively ask -@code{tgetent} to allocate enough space. Pass a null pointer for -@var{buffer}, and @code{tgetent} itself allocates the storage using -@code{malloc}. There is no way to get the address that was allocated, -and you shouldn't try to free the storage.@refill - -With the Unix version of termcap, you must allocate space for the -description yourself and pass the address of the space as the argument -@var{buffer}. There is no way you can tell how much space is needed, so -the convention is to allocate a buffer 2048 characters long and assume that -is enough. (Formerly the convention was to allocate 1024 characters and -assume that was enough. But one day, for one kind of terminal, that was -not enough.) - -No matter how the space to store the description has been obtained, -termcap records its address internally for use when you later interrogate -the description with @code{tgetnum}, @code{tgetstr} or @code{tgetflag}. If -the buffer was allocated by termcap, it will be freed by termcap too if you -call @code{tgetent} again. If the buffer was provided by you, you must -make sure that its contents remain unchanged for as long as you still plan -to interrogate the description.@refill - -The return value of @code{tgetent} is @minus{}1 if there is some difficulty -accessing the data base of terminal types, 0 if the data base is accessible -but the specified type is not defined in it, and some other value -otherwise. - -Here is how you might use the function @code{tgetent}: - -@smallexample -#ifdef unix -static char term_buffer[2048]; -#else -#define term_buffer 0 -#endif - -init_terminal_data () -@{ - char *termtype = getenv ("TERM"); - int success; - - if (termtype == 0) - fatal ("Specify a terminal type with `setenv TERM '.\n"); - - success = tgetent (term_buffer, termtype); - if (success < 0) - fatal ("Could not access the termcap data base.\n"); - if (success == 0) - fatal ("Terminal type `%s' is not defined.\n", termtype); -@} -@end smallexample - -@noindent -Here we assume the function @code{fatal} prints an error message and exits. - -If the environment variable @code{TERMCAP} is defined, its value is used to -override the terminal type data base. The function @code{tgetent} checks -the value of @code{TERMCAP} automatically. If the value starts with -@samp{/} then it is taken as a file name to use as the data base file, -instead of @file{/etc/termcap} which is the standard data base. If the -value does not start with @samp{/} then it is itself used as the terminal -description, provided that the terminal type @var{termtype} is among the -types it claims to apply to. @xref{Data Base}, for information on the -format of a terminal description.@refill - -@node Interrogate, Initialize, Find, Library -@section Interrogating the Terminal Description - -Each piece of information recorded in a terminal description is called a -@dfn{capability}. Each defined terminal capability has a two-letter code -name and a specific meaning. For example, the number of columns is named -@samp{co}. @xref{Capabilities}, for definitions of all the standard -capability names. - -Once you have found the proper terminal description with @code{tgetent} -(@pxref{Find}), your application program must @dfn{interrogate} it for -various terminal capabilities. You must specify the two-letter code of -the capability whose value you seek. - -Capability values can be numeric, boolean (capability is either present or -absent) or strings. Any particular capability always has the same value -type; for example, @samp{co} always has a numeric value, while @samp{am} -(automatic wrap at margin) is always a flag, and @samp{cm} (cursor motion -command) always has a string value. The documentation of each capability -says which type of value it has.@refill - -There are three functions to use to get the value of a capability, -depending on the type of value the capability has. Here are their -declarations in ANSI C: - -@findex tgetnum -@findex tgetflag -@findex tgetstr -@example -int tgetnum (char *@var{name}); -int tgetflag (char *@var{name}); -char *tgetstr (char *@var{name}, char **@var{area}); -@end example - -@table @code -@item tgetnum -Use @code{tgetnum} to get a capability value that is numeric. The -argument @var{name} is the two-letter code name of the capability. If -the capability is present, @code{tgetnum} returns the numeric value -(which is nonnegative). If the capability is not mentioned in the -terminal description, @code{tgetnum} returns @minus{}1. - -@item tgetflag -Use @code{tgetflag} to get a boolean value. If the capability -@var{name} is present in the terminal description, @code{tgetflag} -returns 1; otherwise, it returns 0. - -@item tgetstr -Use @code{tgetstr} to get a string value. It returns a pointer to a -string which is the capability value, or a null pointer if the -capability is not present in the terminal description. - -There are two ways @code{tgetstr} can find space to store the string value: - -@itemize @bullet -@item -You can ask @code{tgetstr} to allocate the space. Pass a null -pointer for the argument @var{area}, and @code{tgetstr} will use -@code{malloc} to allocate storage big enough for the value. -Termcap will never free this storage or refer to it again; you -should free it when you are finished with it. - -This method is more robust, since there is no need to guess how -much space is needed. But it is supported only by the GNU -termcap library. - -@item -You can provide the space. Provide for the argument @var{area} the -address of a pointer variable of type @code{char *}. Before calling -@code{tgetstr}, initialize the variable to point at available space. -Then @code{tgetstr} will store the string value in that space and will -increment the pointer variable to point after the space that has been -used. You can use the same pointer variable for many calls to -@code{tgetstr}. - -There is no way to determine how much space is needed for a single -string, and no way for you to prevent or handle overflow of the area -you have provided. However, you can be sure that the total size of -all the string values you will obtain from the terminal description is -no greater than the size of the description (unless you get the same -capability twice). You can determine that size with @code{strlen} on -the buffer you provided to @code{tgetent}. See below for an example. - -Providing the space yourself is the only method supported by the Unix -version of termcap. -@end itemize -@end table - -Note that you do not have to specify a terminal type or terminal -description for the interrogation functions. They automatically use the -description found by the most recent call to @code{tgetent}. - -Here is an example of interrogating a terminal description for various -capabilities, with conditionals to select between the Unix and GNU methods -of providing buffer space. - -@example -char *tgetstr (); - -char *cl_string, *cm_string; -int height; -int width; -int auto_wrap; - -char PC; /* For tputs. */ -char *BC; /* For tgoto. */ -char *UP; - -interrogate_terminal () -@{ -#ifdef UNIX - /* Here we assume that an explicit term_buffer - was provided to tgetent. */ - char *buffer - = (char *) malloc (strlen (term_buffer)); -#define BUFFADDR &buffer -#else -#define BUFFADDR 0 -#endif - - char *temp; - - /* Extract information we will use. */ - cl_string = tgetstr ("cl", BUFFADDR); - cm_string = tgetstr ("cm", BUFFADDR); - auto_wrap = tgetflag ("am"); - height = tgetnum ("li"); - width = tgetnum ("co"); - - /* Extract information that termcap functions use. */ - temp = tgetstr ("pc", BUFFADDR); - PC = temp ? *temp : 0; - BC = tgetstr ("le", BUFFADDR); - UP = tgetstr ("up", BUFFADDR); -@} -@end example - -@noindent -@xref{Padding}, for information on the variable @code{PC}. @xref{Using -Parameters}, for information on @code{UP} and @code{BC}. - -@node Initialize, Padding, Interrogate, Library -@section Initialization for Use of Termcap -@cindex terminal flags (kernel) - -Before starting to output commands to a terminal using termcap, -an application program should do two things: - -@itemize @bullet -@item -Initialize various global variables which termcap library output -functions refer to. These include @code{PC} and @code{ospeed} for -padding (@pxref{Output Padding}) and @code{UP} and @code{BC} for -cursor motion (@pxref{tgoto}).@refill - -@item -Tell the kernel to turn off alteration and padding of horizontal-tab -characters sent to the terminal. -@end itemize - -To turn off output processing in Berkeley Unix you would use @code{ioctl} -with code @code{TIOCLSET} to set the bit named @code{LLITOUT}, and clear -the bits @code{ANYDELAY} using @code{TIOCSETN}. In POSIX or System V, you -must clear the bit named @code{OPOST}. Refer to the system documentation -for details.@refill - -If you do not set the terminal flags properly, some older terminals will -not work. This is because their commands may contain the characters that -normally signify newline, carriage return and horizontal tab---characters -which the kernel thinks it ought to modify before output. - -When you change the kernel's terminal flags, you must arrange to restore -them to their normal state when your program exits. This implies that the -program must catch fatal signals such as @code{SIGQUIT} and @code{SIGINT} -and restore the old terminal flags before actually terminating. - -Modern terminals' commands do not use these special characters, so if you -do not care about problems with old terminals, you can leave the kernel's -terminal flags unaltered. - -@node Padding, Parameters, Initialize, Library -@section Padding -@cindex padding - -@dfn{Padding} means outputting null characters following a terminal display -command that takes a long time to execute. The terminal description says -which commands require padding and how much; the function @code{tputs}, -described below, outputs a terminal command while extracting from it the -padding information, and then outputs the padding that is necessary. - -@menu -* Why Pad:: Explanation of padding. -* Not Enough:: When there is not enough padding. -* Describe Padding:: The data base says how much padding a terminal needs. -* Output Padding:: Using @code{tputs} to output the needed padding. -@end menu - -@node Why Pad, Not Enough, , Padding -@subsection Why Pad, and How - -Most types of terminal have commands that take longer to execute than they -do to send over a high-speed line. For example, clearing the screen may -take 20msec once the entire command is received. During that time, on a -9600 bps line, the terminal could receive about 20 additional output -characters while still busy clearing the screen. Every terminal has a -certain amount of buffering capacity to remember output characters that -cannot be processed yet, but too many slow commands in a row can cause the -buffer to fill up. Then any additional output that cannot be processed -immediately will be lost. - -To avoid this problem, we normally follow each display command with enough -useless charaters (usually null characters) to fill up the time that the -display command needs to execute. This does the job if the terminal throws -away null characters without using up space in the buffer (which most -terminals do). If enough padding is used, no output can ever be lost. The -right amount of padding avoids loss of output without slowing down -operation, since the time used to transmit padding is time that nothing -else could be done. - -The number of padding characters needed for an operation depends on the -line speed. In fact, it is proportional to the line speed. A 9600 baud -line transmits about one character per msec, so the clear screen command in -the example above would need about 20 characters of padding. At 1200 baud, -however, only about 3 characters of padding are needed to fill up 20msec. - -@node Not Enough, Describe Padding, Why Pad, Padding -@subsection When There Is Not Enough Padding - -There are several common manifestations of insufficient padding. - -@itemize @bullet -@item -Emacs displays @samp{I-search: ^Q-} at the bottom of the screen. - -This means that the terminal thought its buffer was getting full of -display commands, so it tried to tell the computer to stop sending -any. - -@item -The screen is garbled intermittently, or the details of garbling vary -when you repeat the action. (A garbled screen could be due to a -command which is simply incorrect, or to user option in the terminal -which doesn't match the assumptions of the terminal description, but -this usually leads to reproducible failure.) - -This means that the buffer did get full, and some commands were lost. -Many changeable factors can change which ones are lost. - -@item -Screen is garbled at high output speeds but not at low speeds. -Padding problems nearly always go away at low speeds, usually even at -1200 baud. - -This means that a high enough speed permits commands to arrive faster -than they can be executed. -@end itemize - -Although any obscure command on an obscure terminal might lack padding, -in practice problems arise most often from the clearing commands -@samp{cl} and @samp{cd} (@pxref{Clearing}), the scrolling commands -@samp{sf} and @samp{sr} (@pxref{Scrolling}), and the line insert/delete -commands @samp{al} and @samp{dl} (@pxref{Insdel Line}). - -Occasionally the terminal description fails to define @samp{sf} and some -programs will use @samp{do} instead, so you may get a problem with -@samp{do}. If so, first define @samp{sf} just like @samp{do}, then -add some padding to @samp{sf}. - -The best strategy is to add a lot of padding at first, perhaps 200 msec. -This is much more than enough; in fact, it should cause a visible slowdown. -(If you don't see a slowdown, the change has not taken effect; -@pxref{Changing}.) If this makes the problem go away, you have found the -right place to add padding; now reduce the amount until the problem comes -back, then increase it again. If the problem remains, either it is in some -other capability or it is not a matter of padding at all. - -Keep in mind that on many terminals the correct padding for insert/delete -line or for scrolling is cursor-position dependent. If you get problems -from scrolling a large region of the screen but not from scrolling a small -part (just a few lines moving), it may mean that fixed padding should be -replaced with position-dependent padding. - -@node Describe Padding, Output Padding, Not Enough, Padding -@subsection Specifying Padding in a Terminal Description - -In the terminal description, the amount of padding required by each display -command is recorded as a sequence of digits at the front of the command. -These digits specify the padding time in milliseconds (msec). They can be -followed optionally by a decimal point and one more digit, which is a -number of tenths of msec. - -Sometimes the padding needed by a command depends on the cursor position. -For example, the time taken by an ``insert line'' command is usually -proportional to the number of lines that need to be moved down or cleared. -An asterisk (@samp{*}) following the padding time says that the time -should be multiplied by the number of screen lines affected by the command. - -@example -:al=1.3*\E[L: -@end example - -@noindent -is used to describe the ``insert line'' command for a certain terminal. -The padding required is 1.3 msec per line affected. The command itself is -@samp{@key{ESC} [ L}. - -The padding time specified in this way tells @code{tputs} how many pad -characters to output. @xref{Output Padding}. - -Two special capability values affect padding for all commands. These are -the @samp{pc} and @samp{pb}. The variable @samp{pc} specifies the -character to pad with, and @samp{pb} the speed below which no padding is -needed. The defaults for these variables, a null character and 0, -are correct for most terminals. @xref{Pad Specs}. - -@node Output Padding, , Describe Padding, Padding -@subsection Performing Padding with @code{tputs} -@cindex line speed - -@findex tputs -Use the termcap function @code{tputs} to output a string containing an -optional padding spec of the form described above (@pxref{Describe -Padding}). The function @code{tputs} strips off and decodes the padding -spec, outputs the rest of the string, and then outputs the appropriate -padding. Here is its declaration in ANSI C: - -@example -char PC; -short ospeed; - -int tputs (char *@var{string}, int @var{nlines}, int (*@var{outfun}) ()); -@end example - -Here @var{string} is the string (including padding spec) to be output; -@var{nlines} is the number of lines affected by the operation, which is -used to multiply the amount of padding if the padding spec ends with a -@samp{*}. Finally, @var{outfun} is a function (such as @code{fputchar}) -that is called to output each character. When actually called, -@var{outfun} should expect one argument, a character. - -@vindex ospeed -@vindex PC -The operation of @code{tputs} is controlled by two global variables, -@code{ospeed} and @code{PC}. The value of @code{ospeed} is supposed to be -the terminal output speed, encoded as in the @code{ioctl} system call which -gets the speed information. This is needed to compute the number of -padding characters. The value of @code{PC} is the character used for -padding. - -You are responsible for storing suitable values into these variables before -using @code{tputs}. The value stored into the @code{PC} variable should be -taken from the @samp{pc} capability in the terminal description (@pxref{Pad -Specs}). Store zero in @code{PC} if there is no @samp{pc} -capability.@refill - -The argument @var{nlines} requires some thought. Normally, it should be -the number of lines whose contents will be cleared or moved by the command. -For cursor motion commands, or commands that do editing within one line, -use the value 1. For most commands that affect multiple lines, such as -@samp{al} (insert a line) and @samp{cd} (clear from the cursor to the end -of the screen), @var{nlines} should be the screen height minus the current -vertical position (origin 0). For multiple insert and scroll commands such -as @samp{AL} (insert multiple lines), that same value for @var{nlines} is -correct; the number of lines being inserted is @i{not} correct.@refill - -If a ``scroll window'' feature is used to reduce the number of lines -affected by a command, the value of @var{nlines} should take this into -account. This is because the delay time required depends on how much work -the terminal has to do, and the scroll window feature reduces the work. -@xref{Scrolling}. - -Commands such as @samp{ic} and @samp{dc} (insert or delete characters) are -problematical because the padding needed by these commands is proportional -to the number of characters affected, which is the number of columns from -the cursor to the end of the line. It would be nice to have a way to -specify such a dependence, and there is no need for dependence on vertical -position in these commands, so it is an obvious idea to say that for these -commands @var{nlines} should really be the number of columns affected. -However, the definition of termcap clearly says that @var{nlines} is always -the number of lines affected, even in this case, where it is always 1. It -is not easy to change this rule now, because too many programs and terminal -descriptions have been written to follow it. - -Because @var{nlines} is always 1 for the @samp{ic} and @samp{dc} strings, -there is no reason for them to use @samp{*}, but some of them do. These -should be corrected by deleting the @samp{*}. If, some day, such entries -have disappeared, it may be possible to change to a more useful convention -for the @var{nlines} argument for these operations without breaking any -programs. - -@node Parameters, , Padding, Library -@section Filling In Parameters -@cindex parameters - -Some terminal control strings require numeric @dfn{parameters}. For -example, when you move the cursor, you need to say what horizontal and -vertical positions to move it to. The value of the terminal's @samp{cm} -capability, which says how to move the cursor, cannot simply be a string of -characters; it must say how to express the cursor position numbers and -where to put them within the command. - -The specifications of termcap include conventions as to which string-valued -capabilities require parameters, how many parameters, and what the -parameters mean; for example, it defines the @samp{cm} string to take -two parameters, the vertical and horizontal positions, with 0,0 being the -upper left corner. These conventions are described where the individual -commands are documented. - -Termcap also defines a language used within the capability definition for -specifying how and where to encode the parameters for output. This language -uses character sequences starting with @samp{%}. (This is the same idea as -@code{printf}, but the details are different.) The language for parameter -encoding is described in this section. - -A program that is doing display output calls the functions @code{tparam} or -@code{tgoto} to encode parameters according to the specifications. These -functions produce a string containing the actual commands to be output (as -well a padding spec which must be processed with @code{tputs}; -@pxref{Padding}). - -@menu -* Encode Parameters:: The language for encoding parameters. -* Using Parameters:: Outputting a string command with parameters. -@end menu - -@node Encode Parameters, Using Parameters, , Parameters -@subsection Describing the Encoding -@cindex % - -A terminal command string that requires parameters contains special -character sequences starting with @samp{%} to say how to encode the -parameters. These sequences control the actions of @code{tparam} and -@code{tgoto}. - -The parameters values passed to @code{tparam} or @code{tgoto} are -considered to form a vector. A pointer into this vector determines -the next parameter to be processed. Some of the @samp{%}-sequences -encode one parameter and advance the pointer to the next parameter. -Other @samp{%}-sequences alter the pointer or alter the parameter -values without generating output. - -For example, the @samp{cm} string for a standard ANSI terminal is written -as @samp{\E[%i%d;%dH}. (@samp{\E} stands for @key{ESC}.) @samp{cm} by -convention always requires two parameters, the vertical and horizontal goal -positions, so this string specifies the encoding of two parameters. Here -@samp{%i} increments the two values supplied, and each @samp{%d} encodes -one of the values in decimal. If the cursor position values 20,58 are -encoded with this string, the result is @samp{\E[21;59H}. - -First, here are the @samp{%}-sequences that generate output. Except for -@samp{%%}, each of them encodes one parameter and advances the pointer -to the following parameter. - -@table @samp -@item %% -Output a single @samp{%}. This is the only way to represent a literal -@samp{%} in a terminal command with parameters. @samp{%%} does not -use up a parameter. - -@item %d -As in @code{printf}, output the next parameter in decimal. - -@item %2 -Like @samp{%02d} in @code{printf}: output the next parameter in -decimal, and always use at least two digits. - -@item %3 -Like @samp{%03d} in @code{printf}: output the next parameter in -decimal, and always use at least three digits. Note that @samp{%4} -and so on are @emph{not} defined. - -@item %. -Output the next parameter as a single character whose ASCII code is -the parameter value. Like @samp{%c} in @code{printf}. - -@item %+@var{char} -Add the next parameter to the character @var{char}, and output the -resulting character. For example, @samp{%+ } represents 0 as a space, -1 as @samp{!}, etc. -@end table - -The following @samp{%}-sequences specify alteration of the parameters -(their values, or their order) rather than encoding a parameter for output. -They generate no output; they are used only for their side effects -on the parameters. Also, they do not advance the ``next parameter'' pointer -except as explicitly stated. Only @samp{%i}, @samp{%r} and @samp{%>} are -defined in standard Unix termcap. The others are GNU extensions.@refill - -@table @samp -@item %i -Increment the next two parameters. This is used for terminals that -expect cursor positions in origin 1. For example, @samp{%i%d,%d} would -output two parameters with @samp{1} for 0, @samp{2} for 1, etc. - -@item %r -Interchange the next two parameters. This is used for terminals whose -cursor positioning command expects the horizontal position first. - -@item %s -Skip the next parameter. Do not output anything. - -@item %b -Back up one parameter. The last parameter used will become once again -the next parameter to be output, and the next output command will use -it. Using @samp{%b} more than once, you can back up any number of -parameters, and you can refer to each parameter any number of times. - -@item %>@var{c1}@var{c2} -Conditionally increment the next parameter. Here @var{c1} and -@var{c2} are characters which stand for their ASCII codes as numbers. -If the next parameter is greater than the ASCII code of @var{c1}, the -ASCII code of @var{c2} is added to it.@refill - -@item %a @var{op} @var{type} @var{pos} -Perform arithmetic on the next parameter, do not use it up, and do not -output anything. Here @var{op} specifies the arithmetic operation, -while @var{type} and @var{pos} together specify the other operand. - -Spaces are used above to separate the operands for clarity; the spaces -don't appear in the data base, where this sequence is exactly five -characters long. - -The character @var{op} says what kind of arithmetic operation to -perform. It can be any of these characters: - -@table @samp -@item = -assign a value to the next parameter, ignoring its old value. -The new value comes from the other operand. - -@item + -add the other operand to the next parameter. - -@item - -subtract the other operand from the next parameter. - -@item * -multiply the next parameter by the other operand. - -@item / -divide the next parameter by the other operand. -@end table - -The ``other operand'' may be another parameter's value or a constant; -the character @var{type} says which. It can be: - -@table @samp -@item p -Use another parameter. The character @var{pos} says which -parameter to use. Subtract 64 from its ASCII code to get the -position of the desired parameter relative to this one. Thus, -the character @samp{A} as @var{pos} means the parameter after the -next one; the character @samp{?} means the parameter before the -next one. - -@item c -Use a constant value. The character @var{pos} specifies the -value of the constant. The 0200 bit is cleared out, so that 0200 -can be used to represent zero. -@end table -@end table - -The following @samp{%}-sequences are special purpose hacks to compensate -for the weird designs of obscure terminals. They modify the next parameter -or the next two parameters but do not generate output and do not use up any -parameters. @samp{%m} is a GNU extension; the others are defined in -standard Unix termcap. - -@table @samp -@item %n -Exclusive-or the next parameter with 0140, and likewise the parameter -after next. - -@item %m -Complement all the bits of the next parameter and the parameter after next. - -@item %B -Encode the next parameter in BCD. It alters the value of the -parameter by adding six times the quotient of the parameter by ten. -Here is a C statement that shows how the new value is computed: - -@example -@var{parm} = (@var{parm} / 10) * 16 + @var{parm} % 10; -@end example - -@item %D -Transform the next parameter as needed by Delta Data terminals. -This involves subtracting twice the remainder of the parameter by 16. - -@example -@var{parm} -= 2 * (@var{parm} % 16); -@end example -@end table - -@node Using Parameters, , Encode Parameters, Parameters -@subsection Sending Display Commands with Parameters - -The termcap library functions @code{tparam} and @code{tgoto} serve as the -analog of @code{printf} for terminal string parameters. The newer function -@code{tparam} is a GNU extension, more general but missing from Unix -termcap. The original parameter-encoding function is @code{tgoto}, which -is preferable for cursor motion. - -@menu -* tparam:: The general case, for GNU termcap only. -* tgoto:: The special case of cursor motion. -@end menu - -@node tparam, tgoto, , Using Parameters -@subsubsection @code{tparam} - -@findex tparam -The function @code{tparam} can encode display commands with any number of -parameters and allows you to specify the buffer space. It is the preferred -function for encoding parameters for all but the @samp{cm} capability. Its -ANSI C declaration is as follows: - -@smallexample -char *tparam (char *@var{ctlstring}, char *@var{buffer}, int @var{size}, int @var{parm1},...) -@end smallexample - -The arguments are a control string @var{ctlstring} (the value of a terminal -capability, presumably), an output buffer @var{buffer} and @var{size}, and -any number of integer parameters to be encoded. The effect of -@code{tparam} is to copy the control string into the buffer, encoding -parameters according to the @samp{%} sequences in the control string. - -You describe the output buffer by its address, @var{buffer}, and its size -in bytes, @var{size}. If the buffer is not big enough for the data to be -stored in it, @code{tparam} calls @code{malloc} to get a larger buffer. In -either case, @code{tparam} returns the address of the buffer it ultimately -uses. If the value equals @var{buffer}, your original buffer was used. -Otherwise, a new buffer was allocated, and you must free it after you are -done with printing the results. If you pass zero for @var{size} and -@var{buffer}, @code{tparam} always allocates the space with @code{malloc}. - -All capabilities that require parameters also have the ability to specify -padding, so you should use @code{tputs} to output the string produced by -@code{tparam}. @xref{Padding}. Here is an example. - -@example -@{ -char *buf; -char buffer[40]; - -buf = tparam (command, buffer, 40, parm); -tputs (buf, 1, fputchar); -if (buf != buffer) -free (buf); -@} -@end example - -If a parameter whose value is zero is encoded with @samp{%.}-style -encoding, the result is a null character, which will confuse @code{tputs}. -This would be a serious problem, but luckily @samp{%.} encoding is used -only by a few old models of terminal, and only for the @samp{cm} -capability. To solve the problem, use @code{tgoto} rather than -@code{tparam} to encode the @samp{cm} capability.@refill - -@node tgoto, , tparam, Using Parameters -@subsubsection @code{tgoto} - -@findex tgoto -The special case of cursor motion is handled by @code{tgoto}. There -are two reasons why you might choose to use @code{tgoto}: - -@itemize @bullet -@item -For Unix compatibility, because Unix termcap does not have @code{tparam}. - -@item -For the @samp{cm} capability, since @code{tgoto} has a special feature -to avoid problems with null characters, tabs and newlines on certain old -terminal types that use @samp{%.} encoding for that capability. -@end itemize - -Here is how @code{tgoto} might be declared in ANSI C: - -@example -char *tgoto (char *@var{cstring}, int @var{hpos}, int @var{vpos}) -@end example - -There are three arguments, the terminal description's @samp{cm} string and -the two cursor position numbers; @code{tgoto} computes the parametrized -string in an internal static buffer and returns the address of that buffer. -The next time you use @code{tgoto} the same buffer will be reused. - -@vindex UP -@vindex BC -Parameters encoded with @samp{%.} encoding can generate null characters, -tabs or newlines. These might cause trouble: the null character because -@code{tputs} would think that was the end of the string, the tab because -the kernel or other software might expand it into spaces, and the newline -becaue the kernel might add a carriage-return, or padding characters -normally used for a newline. To prevent such problems, @code{tgoto} is -careful to avoid these characters. Here is how this works: if the target -cursor position value is such as to cause a problem (that is to say, zero, -nine or ten), @code{tgoto} increments it by one, then compensates by -appending a string to move the cursor back or up one position. - -The compensation strings to use for moving back or up are found in global -variables named @code{BC} and @code{UP}. These are actual external C -variables with upper case names; they are declared @code{char *}. It is up -to you to store suitable values in them, normally obtained from the -@samp{le} and @samp{up} terminal capabilities in the terminal description -with @code{tgetstr}. Alternatively, if these two variables are both zero, -the feature of avoiding nulls, tabs and newlines is turned off. - -It is safe to use @code{tgoto} for commands other than @samp{cm} only if -you have stored zero in @code{BC} and @code{UP}. - -Note that @code{tgoto} reverses the order of its operands: the horizontal -position comes before the vertical position in the arguments to -@code{tgoto}, even though the vertical position comes before the horizontal -in the parameters of the @samp{cm} string. If you use @code{tgoto} with a -command such as @samp{AL} that takes one parameter, you must pass the -parameter to @code{tgoto} as the ``vertical position''.@refill - -@node Data Base, Capabilities, Library, Top -@chapter The Format of the Data Base - -The termcap data base of terminal descriptions is stored in the file -@file{/etc/termcap}. It contains terminal descriptions, blank lines, and -comments. - -A terminal description starts with one or more names for the terminal type. -The information in the description is a series of @dfn{capability names} -and values. The capability names have standard meanings -(@pxref{Capabilities}) and their values describe the terminal. - -@menu -* Format:: Overall format of a terminal description. -* Capability Format:: Format of capabilities within a description. -* Naming:: Naming conventions for terminal types. -* Inheriting:: Inheriting part of a description from -a related terminal type. -* Changing:: When changes in the data base take effect. -@end menu - -@node Format, Capability Format, , Data Base -@section Terminal Description Format -@cindex description format - -Aside from comments (lines starting with @samp{#}, which are ignored), each -nonblank line in the termcap data base is a terminal description. -A terminal description is nominally a single line, but it can be split -into multiple lines by inserting the two characters @samp{\ newline}. -This sequence is ignored wherever it appears in a description. - -The preferred way to split the description is between capabilities: insert -the four characters @samp{: \ newline tab} immediately before any colon. -This allows each sub-line to start with some indentation. This works -because, after the @samp{\ newline} are ignored, the result is @samp{: tab -:}; the first colon ends the preceding capability and the second colon -starts the next capability. If you split with @samp{\ newline} alone, you -may not add any indentation after them. - -Here is a real example of a terminal description: - -@example -dw|vt52|DEC vt52:\ - :cr=^M:do=^J:nl=^J:bl=^G:\ - :le=^H:bs:cd=\EJ:ce=\EK:cl=\EH\EJ:\ - :cm=\EY%+ %+ :co#80:li#24:\ - :nd=\EC:ta=^I:pt:sr=\EI:up=\EA:\ - :ku=\EA:kd=\EB:kr=\EC:kl=\ED:kb=^H: -@end example - -Each terminal description begins with several names for the terminal type. -The names are separated by @samp{|} characters, and a colon ends the last -name. The first name should be two characters long; it exists only for the -sake of very old Unix systems and is never used in modern systems. The -last name should be a fully verbose name such as ``DEC vt52'' or ``Ann -Arbor Ambassador with 48 lines''. The other names should include whatever -the user ought to be able to specify to get this terminal type, such as -@samp{vt52} or @samp{aaa-48}. @xref{Naming}, for information on how to -choose terminal type names. - -After the terminal type names come the terminal capabilities, separated by -colons and with a colon after the last one. Each capability has a -two-letter name, such as @samp{cm} for ``cursor motion string'' or @samp{li} -for ``number of display lines''. - -@node Capability Format, Naming, Format, Data Base -@section Writing the Capabilities - -There are three kinds of capabilities: flags, numbers, and strings. Each -kind has its own way of being written in the description. Each defined -capability has by convention a particular kind of value; for example, -@samp{li} always has a numeric value and @samp{cm} always a string value. - -A flag capability is thought of as having a boolean value: the value is -true if the capability is present, false if not. When the capability is -present, just write its name between two colons. - -A numeric capability has a value which is a nonnegative number. Write the -capability name, a @samp{#}, and the number, between two colons. For -example, @samp{@dots{}:li#48:@dots{}} is how you specify the @samp{li} -capability for 48 lines.@refill - -A string-valued capability has a value which is a sequence of characters. -Usually these are the characters used to perform some display operation. -Write the capability name, a @samp{=}, and the characters of the value, -between two colons. For example, @samp{@dots{}:cm=\E[%i%d;%dH:@dots{}} is -how the cursor motion command for a standard ANSI terminal would be -specified.@refill - -Special characters in the string value can be expressed using -@samp{\}-escape sequences as in C; in addition, @samp{\E} stands for -@key{ESC}. @samp{^} is also a kind of escape character; @samp{^} followed -by @var{char} stands for the control-equivalent of @var{char}. Thus, -@samp{^a} stands for the character control-a, just like @samp{\001}. -@samp{\} and @samp{^} themselves can be represented as @samp{\\} and -@samp{\^}.@refill - -To include a colon in the string, you must write @samp{\072}. You might -ask, ``Why can't @samp{\:} be used to represent a colon?'' The reason is -that the interrogation functions do not count slashes while looking for a -capability. Even if @samp{:ce=ab\:cd:} were interpreted as giving the -@samp{ce} capability the value @samp{ab:cd}, it would also appear to define -@samp{cd} as a flag. - -The string value will often contain digits at the front to specify padding -(@pxref{Padding}) and/or @samp{%}-sequences within to specify how to encode -parameters (@pxref{Parameters}). Although these things are not to be -output literally to the terminal, they are considered part of the value of -the capability. They are special only when the string value is processed -by @code{tputs}, @code{tparam} or @code{tgoto}. By contrast, @samp{\} and -@samp{^} are considered part of the syntax for specifying the characters -in the string. - -Let's look at the VT52 example again: - -@example -dw|vt52|DEC vt52:\ - :cr=^M:do=^J:nl=^J:bl=^G:\ - :le=^H:bs:cd=\EJ:ce=\EK:cl=\EH\EJ:\ - :cm=\EY%+ %+ :co#80:li#24:\ - :nd=\EC:ta=^I:pt:sr=\EI:up=\EA:\ - :ku=\EA:kd=\EB:kr=\EC:kl=\ED:kb=^H: -@end example - -Here we see the numeric-valued capabilities @samp{co} and @samp{li}, the -flags @samp{bs} and @samp{pt}, and many string-valued capabilities. Most -of the strings start with @key{ESC} represented as @samp{\E}. The rest -contain control characters represented using @samp{^}. The meanings of the -individual capabilities are defined elsewhere (@pxref{Capabilities}). - -@node Naming, Inheriting, Capability Format, Data Base -@section Terminal Type Name Conventions -@cindex names of terminal types - -There are conventions for choosing names of terminal types. For one thing, -all letters should be in lower case. The terminal type for a terminal in -its most usual or most fundamental mode of operation should not have a -hyphen in it. - -If the same terminal has other modes of operation which require -different terminal descriptions, these variant descriptions are given -names made by adding suffixes with hyphens. Such alternate descriptions -are used for two reasons: - -@itemize @bullet -@item -When the terminal has a switch that changes its behavior. Since the -computer cannot tell how the switch is set, the user must tell the -computer by choosing the appropriate terminal type name. - -@cindex wrapping -For example, the VT-100 has a setup flag that controls whether the -cursor wraps at the right margin. If this flag is set to ``wrap'', -you must use the terminal type @samp{vt100-am}. Otherwise you must -use @samp{vt100-nam}. Plain @samp{vt100} is defined as a synonym for -either @samp{vt100-am} or @samp{vt100-nam} depending on the -preferences of the local site.@refill - -The standard suffix @samp{-am} stands for ``automatic margins''. - -@item -To give the user a choice in how to use the terminal. This is done -when the terminal has a switch that the computer normally controls. - -@cindex screen size -For example, the Ann Arbor Ambassador can be configured with many -screen sizes ranging from 20 to 60 lines. Fewer lines make bigger -characters but more lines let you see more of what you are editing. -As a result, users have different preferences. Therefore, termcap -provides terminal types for many screen sizes. If you choose type -@samp{aaa-30}, the terminal will be configured to use 30 lines; if you -choose @samp{aaa-48}, 48 lines will be used, and so on. -@end itemize - -Here is a list of standard suffixes and their conventional meanings: - -@table @samp -@item -w -Short for ``wide''. This is a mode that gives the terminal more -columns than usual. This is normally a user option. - -@item -am -``Automatic margins''. This is an alternate description for use when -the terminal's margin-wrap switch is on; it contains the @samp{am} -flag. The implication is that normally the switch is off and the -usual description for the terminal says that the switch is off. - -@item -nam -``No automatic margins''. The opposite of @samp{-am}, this names an -alternative description which lacks the @samp{am} flag. This implies -that the terminal is normally operated with the margin-wrap switch -turned on, and the normal description of the terminal says so. - -@item -na -``No arrows''. This terminal description initializes the terminal to -keep its arrow keys in local mode. This is a user option. - -@item -rv -``Reverse video''. This terminal description causes text output for -normal video to appear as reverse, and text output for reverse video -to come out as normal. Often this description differs from the usual -one by interchanging the two strings which turn reverse video on and -off.@refill - -This is a user option; you can choose either the ``reverse video'' -variant terminal type or the normal terminal type, and termcap will -obey. - -@item -s -``Status''. Says to enable use of a status line which ordinary output -does not touch (@pxref{Status Line}). - -Some terminals have a special line that is used only as a status line. -For these terminals, there is no need for an @samp{-s} variant; the -status line commands should be defined by default. On other -terminals, enabling a status line means removing one screen line from -ordinary use and reducing the effective screen height. For these -terminals, the user can choose the @samp{-s} variant type to request -use of a status line. - -@item -@var{nlines} -Says to operate with @var{nlines} lines on the screen, for terminals -such as the Ambassador which provide this as an option. Normally this -is a user option; by choosing the terminal type, you control how many -lines termcap will use. - -@item -@var{npages}p -Says that the terminal has @var{npages} pages worth of screen memory, -for terminals where this is a hardware option. - -@item -unk -Says that description is not for direct use, but only for reference in -@samp{tc} capabilities. Such a description is a kind of subroutine, -because it describes the common characteristics of several variant -descriptions that would use other suffixes in place of @samp{-unk}. -@end table - -@node Inheriting, Changing, Naming, Data Base -@section Inheriting from Related Descriptions - -@cindex inheritance -When two terminal descriptions are similar, their identical parts do not -need to be given twice. Instead, one of the two can be defined in terms of -the other, using the @samp{tc} capability. We say that one description -@dfn{refers to} the other, or @dfn{inherits from} the other. - -The @samp{tc} capability must be the last one in the terminal description, -and its value is a string which is the name of another terminal type which -is referred to. For example, - -@example -N9|aaa|ambassador|aaa-30|ann arbor ambassador/30 lines:\ - :ti=\E[2J\E[30;0;0;30p:\ - :te=\E[60;0;0;30p\E[30;1H\E[J:\ - :li#30:tc=aaa-unk: -@end example - -@noindent -defines the terminal type @samp{aaa-30} (also known as plain @samp{aaa}) in -terms of @samp{aaa-unk}, which defines everything about the Ambassador that -is independent of screen height. The types @samp{aaa-36}, @samp{aaa-48} -and so on for other screen heights are likewise defined to inherit from -@samp{aaa-unk}. - -The capabilities overridden by @samp{aaa-30} include @samp{li}, which says -how many lines there are, and @samp{ti} and @samp{te}, which configure the -terminal to use that many lines. - -The effective terminal description for type @samp{aaa} consists of the text -shown above followed by the text of the description of @samp{aaa-unk}. The -@samp{tc} capability is handled automatically by @code{tgetent}, which -finds the description thus referenced and combines the two descriptions -(@pxref{Find}). Therefore, only the implementor of the terminal -descriptions needs to think about using @samp{tc}. Users and application -programmers do not need to be concerned with it. - -Since the reference terminal description is used last, capabilities -specified in the referring description override any specifications of the -same capabilities in the reference description. - -The referring description can cancel out a capability without specifying -any new value for it by means of a special trick. Write the capability in -the referring description, with the character @samp{@@} after the capability -name, as follows: - -@smallexample -NZ|aaa-30-nam|ann arbor ambassador/30 lines/no automatic-margins:\ - :am@@:tc=aaa-30: -@end smallexample - -@node Changing, , Inheriting, Data Base -@section When Changes in the Data Base Take Effect - -Each application program must read the terminal description from the -data base, so a change in the data base is effective for all jobs started -after the change is made. - -The change will usually have no effect on a job that have been in existence -since before the change. The program probably read the terminal description -once, when it was started, and is continuing to use what it read then. -If the program does not have a feature for reexamining the data base, then -you will need to run it again (probably killing the old job). - -If the description in use is coming from the @code{TERMCAP} environment -variable, then the data base file is effectively overridden, and changes in -it will have no effect until you change the @code{TERMCAP} variable as -well. For example, some users' @file{.login} files automatically copy the -terminal description into @code{TERMCAP} to speed startup of applications. -If you have done this, you will need to change the @code{TERMCAP} variable -to make the changed data base take effect. - -@node Capabilities, Summary, Data Base, Top -@chapter Definitions of the Terminal Capabilities - -This section is divided into many subsections, each for one aspect of -use of display terminals. For writing a display program, you usually need -only check the subsections for the operations you want to use. For writing -a terminal description, you must read each subsection and fill in the -capabilities described there. - -String capabilities that are display commands may require numeric -parameters (@pxref{Parameters}). Most such capabilities do not use -parameters. When a capability requires parameters, this is explicitly -stated at the beginning of its definition. In simple cases, the first or -second sentence of the definition mentions all the parameters, in the order -they should be given, using a name -@iftex -in italics -@end iftex -@ifinfo -in upper case -@end ifinfo -for each one. For example, the @samp{rp} capability is a command that -requires two parameters; its definition begins as follows: - -@quotation -String of commands to output a graphic character @var{c}, repeated @var{n} -times. -@end quotation - -In complex cases or when there are many parameters, they are described -explicitly. - -When a capability is described as obsolete, this means that programs should -not be written to look for it, but terminal descriptions should still be -written to provide it. - -When a capability is described as very obsolete, this means that it should -be omitted from terminal descriptions as well. - -@menu -* Basic:: Basic characteristics. -* Screen Size:: Screen size, and what happens when it changes. -* Cursor Motion:: Various ways to move the cursor. -* Wrapping:: What happens if you write a character in the last column. -* Scrolling:: Pushing text up and down on the screen. -* Windows:: Limiting the part of the window that output affects. -* Clearing:: Erasing one or many lines. -* Insdel Line:: Making new blank lines in mid-screen; deleting lines. -* Insdel Char:: Inserting and deleting characters within a line. -* Standout:: Highlighting some of the text. -* Underlining:: Underlining some of the text. -* Cursor Visibility:: Making the cursor more or less easy to spot. -* Bell:: Attracts user's attention; not localized on the screen. -* Keypad:: Recognizing when function keys or arrows are typed. -* Meta Key:: @key{META} acts like an extra shift key. -* Initialization:: Commands used to initialize or reset the terminal. -* Pad Specs:: Info for the kernel on how much padding is needed. -* Status Line:: A status line displays ``background'' information. -* Half-Line:: Moving by half-lines, for superscripts and subscripts. -* Printer:: Controlling auxiliary printers of display terminals. -@end menu - -@node Basic, Screen Size, , Capabilities -@section Basic Characteristics - -This section documents the capabilities that describe the basic and -nature of the terminal, and also those that are relevant to the output -of graphic characters. - -@table @samp -@item os -@kindex os -@cindex overstrike -Flag whose presence means that the terminal can overstrike. This -means that outputting a graphic character does not erase whatever was -present in the same character position before. The terminals that can -overstrike include printing terminals, storage tubes (all obsolete -nowadays), and many bit-map displays. - -@item eo -@kindex eo -Flag whose presence means that outputting a space erases a character -position even if the terminal supports overstriking. If this flag is -not present and overstriking is supported, output of a space has no -effect except to move the cursor. - -(On terminals that do not support overstriking, you can always assume -that outputting a space at a position erases whatever character was -previously displayed there.) - -@item gn -@kindex gn -@cindex generic terminal type -Flag whose presence means that this terminal type is a generic type -which does not really describe any particular terminal. Generic types -are intended for use as the default type assigned when the user -connects to the system, with the intention that the user should -specify what type he really has. One example of a generic type -is the type @samp{network}. - -Since the generic type cannot say how to do anything interesting with -the terminal, termcap-using programs will always find that the -terminal is too weak to be supported if the user has failed to specify -a real terminal type in place of the generic one. The @samp{gn} flag -directs these programs to use a different error message: ``You have -not specified your real terminal type'', rather than ``Your terminal -is not powerful enough to be used''. - -@item hc -@kindex hc -Flag whose presence means this is a hardcopy terminal. - -@item rp -@kindex rp -@cindex repeat output -String of commands to output a graphic character @var{c}, repeated @var{n} -times. The first parameter value is the ASCII code for the desired -character, and the second parameter is the number of times to repeat the -character. Often this command requires padding proportional to the -number of times the character is repeated. This effect can be had by -using parameter arithmetic with @samp{%}-sequences to compute the -amount of padding, then generating the result as a number at the front -of the string so that @code{tputs} will treat it as padding. - -@item hz -@kindex hz -Flag whose presence means that the ASCII character @samp{~} cannot be -output on this terminal because it is used for display commands. - -Programs handle this flag by checking all text to be output and -replacing each @samp{~} with some other character(s). If this is not -done, the screen will be thoroughly garbled. - -The old Hazeltine terminals that required such treatment are probably -very rare today, so you might as well not bother to support this flag. - -@item CC -@kindex CC -@cindex command character -String whose presence means the terminal has a settable command -character. The value of the string is the default command character -(which is usually @key{ESC}). - -All the strings of commands in the terminal description should be -written to use the default command character. If you are writing an -application program that changes the command character, use the -@samp{CC} capability to figure out how to translate all the display -commands to work with the new command character. - -Most programs have no reason to look at the @samp{CC} capability. - -@item xb -@kindex xb -@cindex Superbee -Flag whose presence identifies Superbee terminals which are unable to -transmit the characters @key{ESC} and @kbd{Control-C}. Programs which -support this flag are supposed to check the input for the code sequences -sent by the @key{F1} and @key{F2} keys, and pretend that @key{ESC} -or @kbd{Control-C} (respectively) had been read. But this flag is -obsolete, and not worth supporting. -@end table - -@node Screen Size, Cursor Motion, Basic, Capabilities -@section Screen Size -@cindex screen size - -A terminal description has two capabilities, @samp{co} and @samp{li}, -that describe the screen size in columns and lines. But there is more -to the question of screen size than this. - -On some operating systems the ``screen'' is really a window and the -effective width can vary. On some of these systems, @code{tgetnum} -uses the actual width of the window to decide what value to return for -the @samp{co} capability, overriding what is actually written in the -terminal description. On other systems, it is up to the application -program to check the actual window width using a system call. For -example, on BSD 4.3 systems, the system call @code{ioctl} with code -@code{TIOCGWINSZ} will tell you the current screen size. - -On all window systems, termcap is powerless to advise the application -program if the user resizes the window. Application programs must -deal with this possibility in a system-dependent fashion. On some -systems the C shell handles part of the problem by detecting changes -in window size and setting the @code{TERMCAP} environment variable -appropriately. This takes care of application programs that are -started subsequently. It does not help application programs already -running. - -On some systems, including BSD 4.3, all programs using a terminal get -a signal named @code{SIGWINCH} whenever the screen size changes. -Programs that use termcap should handle this signal by using -@code{ioctl TIOCGWINSZ} to learn the new screen size. - -@table @samp -@item co -@kindex co -@cindex screen size -Numeric value, the width of the screen in character positions. Even -hardcopy terminals normally have a @samp{co} capability. - -@item li -@kindex li -Numeric value, the height of the screen in lines. -@end table - -@node Cursor Motion, Wrapping, Screen Size, Capabilities -@section Cursor Motion -@cindex cursor motion - -Termcap assumes that the terminal has a @dfn{cursor}, a spot on the screen -where a visible mark is displayed, and that most display commands take -effect at the position of the cursor. It follows that moving the cursor -to a specified location is very important. - -There are many terminal capabilities for different cursor motion -operations. A terminal description should define as many as possible, but -most programs do not need to use most of them. One capability, @samp{cm}, -moves the cursor to an arbitrary place on the screen; this by itself is -sufficient for any application as long as there is no need to support -hardcopy terminals or certain old, weak displays that have only relative -motion commands. Use of other cursor motion capabilities is an -optimization, enabling the program to output fewer characters in some -common cases. - -If you plan to use the relative cursor motion commands in an application -program, you must know what the starting cursor position is. To do this, -you must keep track of the cursor position and update the records each -time anything is output to the terminal, including graphic characters. -In addition, it is necessary to know whether the terminal wraps after -writing in the rightmost column. @xref{Wrapping}. - -One other motion capability needs special mention: @samp{nw} moves the -cursor to the beginning of the following line, perhaps clearing all the -starting line after the cursor, or perhaps not clearing at all. This -capability is a least common denominator that is probably supported even by -terminals that cannot do most other things such as @samp{cm} or @samp{do}. -Even hardcopy terminals can support @samp{nw}. - -@table @asis -@item @samp{cm} -@kindex cm -String of commands to position the cursor at line @var{l}, column @var{c}. -Both parameters are origin-zero, and are defined relative to the -screen, not relative to display memory. - -All display terminals except a few very obsolete ones support @samp{cm}, -so it is acceptable for an application program to refuse to operate on -terminals lacking @samp{cm}. - -@item @samp{ho} -@kindex ho -@cindex home position -String of commands to move the cursor to the upper left corner of the -screen (this position is called the @dfn{home position}). In -terminals where the upper left corner of the screen is not the same as -the beginning of display memory, this command must go to the upper -left corner of the screen, not the beginning of display memory. - -Every display terminal supports this capability, and many application -programs refuse to operate if the @samp{ho} capability is missing. - -@item @samp{ll} -@kindex ll -String of commands to move the cursor to the lower left corner of the -screen. On some terminals, moving up from home position does this, -but programs should never assume that will work. Just output the -@samp{ll} string (if it is provided); if moving to home position and -then moving up is the best way to get there, the @samp{ll} command -will do that. - -@item @samp{cr} -@kindex cr -String of commands to move the cursor to the beginning of the line it -is on. If this capability is not specified, many programs assume -they can use the ASCII carriage return character for this. - -@item @samp{le} -@kindex le -String of commands to move the cursor left one column. Unless the -@samp{bw} flag capability is specified, the effect is undefined if the -cursor is at the left margin; do not use this command there. If -@samp{bw} is present, this command may be used at the left margin, and -it wraps the cursor to the last column of the preceding line. - -@item @samp{nd} -@kindex nd -String of commands to move the cursor right one column. The effect is -undefined if the cursor is at the right margin; do not use this -command there, not even if @samp{am} is present. - -@item @samp{up} -@kindex up -String of commands to move the cursor vertically up one line. The -effect of sending this string when on the top line is undefined; -programs should never use it that way. - -@item @samp{do} -@kindex do -String of commands to move the cursor vertically down one line. The -effect of sending this string when on the bottom line is undefined; -programs should never use it that way. - -Some programs do use @samp{do} to scroll up one line if used at the -bottom line, if @samp{sf} is not defined but @samp{sr} is. This is -only to compensate for certain old, incorrect terminal descriptions. -(In principle this might actually lead to incorrect behavior on other -terminals, but that seems to happen rarely if ever.) But the proper -solution is that the terminal description should define @samp{sf} as -well as @samp{do} if the command is suitable for scrolling. - -The original idea was that this string would not contain a newline -character and therefore could be used without disabling the kernel's -usual habit of converting of newline into a carriage-return newline -sequence. But many terminal descriptions do use newline in the -@samp{do} string, so this is not possible; a program which sends the -@samp{do} string must disable output conversion in the kernel -(@pxref{Initialize}). - -@item @samp{bw} -@kindex bw -Flag whose presence says that @samp{le} may be used in column zero -to move to the last column of the preceding line. If this flag -is not present, @samp{le} should not be used in column zero. - -@item @samp{nw} -@kindex nw -String of commands to move the cursor to start of next line, possibly -clearing rest of line (following the cursor) before moving. - -@item @samp{DO}, @samp{UP}, @samp{LE}, @samp{RI} -@kindex DO -@kindex LE -@kindex RI -@kindex UP -Strings of commands to move the cursor @var{n} lines down vertically, -up vertically, or @var{n} columns left or right. Do not attempt to -move past any edge of the screen with these commands; the effect of -trying that is undefined. Only a few terminal descriptions provide -these commands, and most programs do not use them. - -@item @samp{CM} -@kindex CM -String of commands to position the cursor at line @var{l}, column -@var{c}, relative to display memory. Both parameters are origin-zero. -This capability is present only in terminals where there is a -difference between screen-relative and memory-relative addressing, and -not even in all such terminals. - -@item @samp{ch} -@kindex ch -String of commands to position the cursor at column @var{c} in the -same line it is on. This is a special case of @samp{cm} in which the -vertical position is not changed. The @samp{ch} capability is -provided only when it is faster to output than @samp{cm} would be in -this special case. Programs should not assume most display terminals -have @samp{ch}. - -@item @samp{cv} -@kindex cv -String of commands to position the cursor at line @var{l} in the same -column. This is a special case of @samp{cm} in which the horizontal -position is not changed. The @samp{cv} capability is provided only -when it is faster to output than @samp{cm} would be in this special -case. Programs should not assume most display terminals have -@samp{cv}. - -@item @samp{sc} -@kindex sc -String of commands to make the terminal save the current cursor -position. Only the last saved position can be used. If this -capability is present, @samp{rc} should be provided also. Most -terminals have neither. - -@item @samp{rc} -@kindex rc -String of commands to make the terminal restore the last saved cursor -position. If this capability is present, @samp{sc} should be provided -also. Most terminals have neither. - -@item @samp{ff} -@kindex ff -String of commands to advance to the next page, for a hardcopy -terminal. - -@item @samp{ta} -@kindex ta -String of commands to move the cursor right to the next hardware tab -stop column. Missing if the terminal does not have any kind of -hardware tabs. Do not send this command if the kernel's terminal -modes say that the kernel is expanding tabs into spaces. - -@item @samp{bt} -@kindex bt -String of commands to move the cursor left to the previous hardware -tab stop column. Missing if the terminal has no such ability; many -terminals do not. Do not send this command if the kernel's terminal -modes say that the kernel is expanding tabs into spaces. -@end table - -The following obsolete capabilities should be included in terminal -descriptions when appropriate, but should not be looked at by new programs. - -@table @samp -@item nc -@kindex nc -Flag whose presence means the terminal does not support the ASCII -carriage return character as @samp{cr}. This flag is needed because -old programs assume, when the @samp{cr} capability is missing, that -ASCII carriage return can be used for the purpose. We use @samp{nc} -to tell the old programs that carriage return may not be used. - -New programs should not assume any default for @samp{cr}, so they need -not look at @samp{nc}. However, descriptions should contain @samp{nc} -whenever they do not contain @samp{cr}. - -@item xt -@kindex xt -Flag whose presence means that the ASCII tab character may not be used -for cursor motion. This flag exists because old programs assume, when -the @samp{ta} capability is missing, that ASCII tab can be used for -the purpose. We use @samp{xt} to tell the old programs not to use tab. - -New programs should not assume any default for @samp{ta}, so they need -not look at @samp{xt} in connection with cursor motion. Note that -@samp{xt} also has implications for standout mode (@pxref{Standout}). -It is obsolete in regard to cursor motion but not in regard to -standout. - -In fact, @samp{xt} means that the terminal is a Teleray 1061. - -@item bc -@kindex bc -Very obsolete alternative name for the @samp{le} capability. - -@item bs -@kindex bs -Flag whose presence means that the ASCII character backspace may be -used to move the cursor left. Obsolete; look at @samp{le} instead. - -@item nl -@kindex nl -Obsolete capability which is a string that can either be used to move -the cursor down or to scroll. The same string must scroll when used -on the bottom line and move the cursor when used on any other line. -New programs should use @samp{do} or @samp{sf}, and ignore @samp{nl}. - -If there is no @samp{nl} capability, some old programs assume they can -use the newline character for this purpose. These programs follow a -bad practice, but because they exist, it is still desirable to define -the @samp{nl} capability in a terminal description if the best way to -move down is @emph{not} a newline. -@end table - -@node Wrapping, Scrolling, Cursor Motion, Capabilities -@section Wrapping -@cindex wrapping - -@dfn{Wrapping} means moving the cursor from the right margin to the left -margin of the following line. Some terminals wrap automatically when a -graphic character is output in the last column, while others do not. Most -application programs that use termcap need to know whether the terminal -wraps. There are two special flag capabilities to describe what the -terminal does when a graphic character is output in the last column. - -@table @samp -@item am -@kindex am -Flag whose presence means that writing a character in the last column -causes the cursor to wrap to the beginning of the next line. - -If @samp{am} is not present, writing in the last column leaves the -cursor at the place where the character was written. - -Writing in the last column of the last line should be avoided on -terminals with @samp{am}, as it may or may not cause scrolling to -occur (@pxref{Scrolling}). Scrolling is surely not what you would -intend. - -If your program needs to check the @samp{am} flag, then it also needs -to check the @samp{xn} flag which indicates that wrapping happens in a -strange way. Many common terminals have the @samp{xn} flag. - -@item xn -@kindex xn -Flag whose presence means that the cursor wraps in a strange way. At -least two distinct kinds of strange behavior are known; the termcap -data base does not contain anything to distinguish the two. - -On Concept-100 terminals, output in the last column wraps the cursor -almost like an ordinary @samp{am} terminal. But if the next thing -output is a newline, it is ignored. - -DEC VT-100 terminals (when the wrap switch is on) do a different -strange thing: the cursor wraps only if the next thing output is -another graphic character. In fact, the wrap occurs when the -following graphic character is received by the terminal, before the -character is placed on the screen. - -On both of these terminals, after writing in the last column a -following graphic character will be displayed in the first column of -the following line. But the effect of relative cursor motion -characters such as newline or backspace at such a time depends on the -terminal. The effect of erase or scrolling commands also depends on -the terminal. You can't assume anything about what they will do on a -terminal that has @samp{xn}. So, to be safe, you should never do -these things at such a time on such a terminal. - -To be sure of reliable results on a terminal which has the @samp{xn} -flag, output a @samp{cm} absolute positioning command after writing in -the last column. Another safe thing to do is to output carriage-return -newline, which will leave the cursor at the beginning of the following -line. - -@item LP -@kindex LP -Flag whose presence means that it is safe to write in the last column of -the last line without worrying about undesired scrolling. @samp{LP} -indicates the DEC flavor of @samp{xn} strangeness. -@end table - -@node Scrolling, Windows, Wrapping, Capabilities -@section Scrolling -@cindex scrolling - -@dfn{Scrolling} means moving the contents of the screen up or down one or -more lines. Moving the contents up is @dfn{forward scrolling}; moving them -down is @dfn{reverse scrolling}. - -Scrolling happens after each line of output during ordinary output on most -display terminals. But in an application program that uses termcap for -random-access output, scrolling happens only when explicitly requested with -the commands in this section. - -Some terminals have a @dfn{scroll region} feature. This lets you limit -the effect of scrolling to a specified range of lines. Lines outside the -range are unaffected when scrolling happens. The scroll region feature -is available if either @samp{cs} or @samp{cS} is present. - -@table @samp -@item sf -@kindex sf -String of commands to scroll the screen one line up, assuming it is -output with the cursor at the beginning of the bottom line. - -@item sr -@kindex sr -String of commands to scroll the screen one line down, assuming it is -output with the cursor at the beginning of the top line. - -@item do -A few programs will try to use @samp{do} to do the work of @samp{sf}. -This is not really correct---it is an attempt to compensate for the -absence of a @samp{sf} command in some old terminal descriptions. - -Since these terminal descriptions do define @samp{sr}, perhaps at one -time the definition of @samp{do} was different and it could be used -for scrolling as well. But it isn't desirable to combine these two -functions in one capability, since scrolling often requires more -padding than simply moving the cursor down. Defining @samp{sf} and -@samp{do} separately allows you to specify the padding properly. -Also, all sources agree that @samp{do} should not be relied on to do -scrolling. - -So the best approach is to add @samp{sf} capabilities to the -descriptions of these terminals, copying the definition of @samp{do} -if that does scroll. - -@item SF -@kindex SF -String of commands to scroll the screen @var{n} lines up, assuming it -is output with the cursor at the beginning of the bottom line. - -@item SR -@kindex SR -String of commands to scroll the screen @var{n} lines down, assuming it -is output with the cursor at the beginning of the top line. - -@item cs -@kindex cs -String of commands to set the scroll region. This command takes two -parameters, @var{start} and @var{end}, which are the line numbers -(origin-zero) of the first line to include in the scroll region and of -the last line to include in it. When a scroll region is set, -scrolling is limited to the specified range of lines; lines outside -the range are not affected by scroll commands. - -Do not try to move the cursor outside the scroll region. The region -remains set until explicitly removed. To remove the scroll region, -use another @samp{cs} command specifying the full height of the -screen. - -The cursor position is undefined after the @samp{cs} command is set, -so position the cursor with @samp{cm} immediately afterward. - -@item cS -@kindex cS -String of commands to set the scroll region using parameters in -different form. The effect is the same as if @samp{cs} were used. -Four parameters are required: - -@enumerate -@item -Total number of lines on the screen. -@item -Number of lines above desired scroll region. -@item -Number of lines below (outside of) desired scroll region. -@item -Total number of lines on the screen, the same as the first parameter. -@end enumerate - -This capability is a GNU extension that was invented to allow the Ann -Arbor Ambassador's scroll-region command to be described; it could -also be done by putting non-Unix @samp{%}-sequences into a @samp{cs} -string, but that would have confused Unix programs that used the -@samp{cs} capability with the Unix termcap. Currently only GNU Emacs -uses the @samp{cS} capability. - -@item ns -@kindex ns -Flag which means that the terminal does not normally scroll for -ordinary sequential output. For modern terminals, this means that -outputting a newline in ordinary sequential output with the cursor on -the bottom line wraps to the top line. For some obsolete terminals, -other things may happen. - -The terminal may be able to scroll even if it does not normally do so. -If the @samp{sf} capability is provided, it can be used for scrolling -regardless of @samp{ns}. - -@item da -@kindex da -Flag whose presence means that lines scrolled up off the top of the -screen may come back if scrolling down is done subsequently. - -The @samp{da} and @samp{db} flags do not, strictly speaking, affect -how to scroll. But programs that scroll usually need to clear the -lines scrolled onto the screen, if these flags are present. - -@item db -@kindex db -Flag whose presence means that lines scrolled down off the bottom of -the screen may come back if scrolling up is done subsequently. - -@item lm -@kindex lm -Numeric value, the number of lines of display memory that the terminal -has. A value of zero means that the terminal has more display memory -than can fit on the screen, but no fixed number of lines. (The number -of lines may depend on the amount of text in each line.) -@end table - -Any terminal description that defines @samp{SF} should also define @samp{sf}; -likewise for @samp{SR} and @samp{sr}. However, many terminals can only -scroll by one line at a time, so it is common to find @samp{sf} and not -@samp{SF}, or @samp{sr} without @samp{SR}.@refill - -Therefore, all programs that use the scrolling facilities should be -prepared to work with @samp{sf} in the case that @samp{SF} is absent, and -likewise with @samp{sr}. On the other hand, an application program that -uses only @samp{sf} and not @samp{SF} is acceptable, though slow on some -terminals.@refill - -When outputting a scroll command with @code{tputs}, the @var{nlines} -argument should be the total number of lines in the portion of the screen -being scrolled. Very often these commands require padding proportional to -this number of lines. @xref{Padding}. - -@node Windows, Clearing, Scrolling, Capabilities -@section Windows -@cindex window - -A @dfn{window}, in termcap, is a rectangular portion of the screen to which -all display operations are restricted. Wrapping, clearing, scrolling, -insertion and deletion all operate as if the specified window were all the -screen there was. - -@table @samp -@item wi -@kindex wi -String of commands to set the terminal output screen window. -This string requires four parameters, all origin-zero: -@enumerate -@item -The first line to include in the window. -@item -The last line to include in the window. -@item -The first column to include in the window. -@item -The last column to include in the window. -@end enumerate -@end table - -Most terminals do not support windows. - -@node Clearing, Insdel Line, Windows, Capabilities -@section Clearing Parts of the Screen -@cindex erasing -@cindex clearing the screen - -There are several terminal capabilities for clearing parts of the screen -to blank. All display terminals support the @samp{cl} string, and most -display terminals support all of these capabilities. - -@table @samp -@item cl -@kindex cl -String of commands to clear the entire screen and position the cursor -at the upper left corner. - -@item cd -@kindex cd -String of commands to clear the line the cursor is on, and all the -lines below it, down to the bottom of the screen. This command string -should be used only with the cursor in column zero; their effect is -undefined if the cursor is elsewhere. - -@item ce -@kindex ce -String of commands to clear from the cursor to the end of the current -line. - -@item ec -@kindex ec -String of commands to clear @var{n} characters, starting with the -character that the cursor is on. This command string is expected to -leave the cursor position unchanged. The parameter @var{n} should never -be large enough to reach past the right margin; the effect of such a -large parameter would be undefined. -@end table - -Clear to end of line (@samp{ce}) is extremely important in programs that -maintain an updating display. Nearly all display terminals support this -operation, so it is acceptable for a an application program to refuse to -work if @samp{ce} is not present. However, if you do not want this -limitation, you can accomplish clearing to end of line by outputting spaces -until you reach the right margin. In order to do this, you must know the -current horizontal position. Also, this technique assumes that writing a -space will erase. But this happens to be true on all the display terminals -that fail to support @samp{ce}. - -@node Insdel Line, Insdel Char, Clearing, Capabilities -@section Insert/Delete Line - -@cindex insert line -@cindex delete line -@dfn{Inserting a line} means creating a blank line in the middle -of the screen, and pushing the existing lines of text apart. In fact, -the lines above the insertion point do not change, while the lines below -move down, and one is normally lost at the bottom of the screen. - -@dfn{Deleting a line} means causing the line to disappear from the screen, -closing up the gap by moving the lines below it upward. A new line -appears at the bottom of the screen. Usually this line is blank, but -on terminals with the @samp{db} flag it may be a line previously moved -off the screen bottom by scrolling or line insertion. - -Insertion and deletion of lines is useful in programs that maintain an -updating display some parts of which may get longer or shorter. They are -also useful in editors for scrolling parts of the screen, and for -redisplaying after lines of text are killed or inserted. - -Many terminals provide commands to insert or delete a single line at the -cursor position. Some provide the ability to insert or delete several -lines with one command, using the number of lines to insert or delete as a -parameter. Always move the cursor to column zero before using any of -these commands. - -@table @samp -@item al -@kindex al -String of commands to insert a blank line before the line the cursor -is on. The existing line, and all lines below it, are moved down. -The last line in the screen (or in the scroll region, if one is set) -disappears and in most circumstances is discarded. It may not be -discarded if the @samp{db} is present (@pxref{Scrolling}). - -The cursor must be at the left margin before this command is used. -This command does not move the cursor. - -@item dl -@kindex dl -String of commands to delete the line the cursor is on. The following -lines move up, and a blank line appears at the bottom of the screen -(or bottom of the scroll region). If the terminal has the @samp{db} -flag, a nonblank line previously pushed off the screen bottom may -reappear at the bottom. - -The cursor must be at the left margin before this command is used. -This command does not move the cursor. - -@item AL -@kindex AL -String of commands to insert @var{n} blank lines before the line that -the cursor is on. It is like @samp{al} repeated @var{n} times, except -that it is as fast as one @samp{al}. - -@item DL -@kindex DL -String of commands to delete @var{n} lines starting with the line that -the cursor is on. It is like @samp{dl} repeated @var{n} times, except -that it is as fast as one @samp{dl}. -@end table - -Any terminal description that defines @samp{AL} should also define -@samp{al}; likewise for @samp{DL} and @samp{dl}. However, many terminals -can only insert or delete one line at a time, so it is common to find -@samp{al} and not @samp{AL}, or @samp{dl} without @samp{DL}.@refill - -Therefore, all programs that use the insert and delete facilities should be -prepared to work with @samp{al} in the case that @samp{AL} is absent, and -likewise with @samp{dl}. On the other hand, it is acceptable to write -an application that uses only @samp{al} and @samp{dl} and does not look -for @samp{AL} or @samp{DL} at all.@refill - -If a terminal does not support line insertion and deletion directly, -but does support a scroll region, the effect of insertion and deletion -can be obtained with scrolling. However, it is up to the individual -user program to check for this possibility and use the scrolling -commands to get the desired result. It is fairly important to implement -this alternate strategy, since it is the only way to get the effect of -line insertion and deletion on the popular VT100 terminal. - -Insertion and deletion of lines is affected by the scroll region on -terminals that have a settable scroll region. This is useful when it is -desirable to move any few consecutive lines up or down by a few lines. -@xref{Scrolling}. - -The line pushed off the bottom of the screen is not lost if the terminal -has the @samp{db} flag capability; instead, it is pushed into display -memory that does not appear on the screen. This is the same thing that -happens when scrolling pushes a line off the bottom of the screen. -Either reverse scrolling or deletion of a line can bring the apparently -lost line back onto the bottom of the screen. If the terminal has the -scroll region feature as well as @samp{db}, the pushed-out line really -is lost if a scroll region is in effect. - -When outputting an insert or delete command with @code{tputs}, the -@var{nlines} argument should be the total number of lines from the cursor -to the bottom of the screen (or scroll region). Very often these commands -require padding proportional to this number of lines. @xref{Padding}. - -For @samp{AL} and @samp{DL} the @var{nlines} argument should @emph{not} -depend on the number of lines inserted or deleted; only the total number of -lines affected. This is because it is just as fast to insert two or -@var{n} lines with @samp{AL} as to insert one line with @samp{al}. - -@node Insdel Char, Standout, Insdel Line, Capabilities -@section Insert/Delete Character -@cindex insert character -@cindex delete character - -@dfn{Inserting a character} means creating a blank space in the middle of a -line, and pushing the rest of the line rightward. The character in the -rightmost column is lost. - -@dfn{Deleting a character} means causing the character to disappear from -the screen, closing up the gap by moving the rest of the line leftward. A -blank space appears in the rightmost column. - -Insertion and deletion of characters is useful in programs that maintain an -updating display some parts of which may get longer or shorter. It is also -useful in editors for redisplaying the results of editing within a line. - -Many terminals provide commands to insert or delete a single character at -the cursor position. Some provide the ability to insert or delete several -characters with one command, using the number of characters to insert or -delete as a parameter. - -@cindex insert mode -Many terminals provide an insert mode in which outputting a graphic -character has the added effect of inserting a position for that character. -A special command string is used to enter insert mode and another is used -to exit it. The reason for designing a terminal with an insert mode rather -than an insert command is that inserting character positions is usually -followed by writing characters into them. With insert mode, this is as -fast as simply writing the characters, except for the fixed overhead of -entering and leaving insert mode. However, when the line speed is great -enough, padding may be required for the graphic characters output in insert -mode. - -Some terminals require you to enter insert mode and then output a special -command for each position to be inserted. Or they may require special -commands to be output before or after each graphic character to be -inserted. - -@cindex delete mode -Deletion of characters is usually accomplished by a straightforward command -to delete one or several positions; but on some terminals, it is necessary -to enter a special delete mode before using the delete command, and leave -delete mode afterward. Sometimes delete mode and insert mode are the same -mode. - -Some terminals make a distinction between character positions in which a -space character has been output and positions which have been cleared. On -these terminals, the effect of insert or delete character runs to the first -cleared position rather than to the end of the line. In fact, the effect -may run to more than one line if there is no cleared position to stop the -shift on the first line. These terminals are identified by the @samp{in} -flag capability. - -On terminals with the @samp{in} flag, the technique of skipping over -characters that you know were cleared, and then outputting text later on in -the same line, causes later insert and delete character operations on that -line to do nonstandard things. A program that has any chance of doing this -must check for the @samp{in} flag and must be careful to write explicit -space characters into the intermediate columns when @samp{in} is present. - -A plethora of terminal capabilities are needed to describe all of this -complexity. Here is a list of them all. Following the list, we present -an algorithm for programs to use to take proper account of all of these -capabilities. - -@table @samp -@item im -@kindex im -String of commands to enter insert mode. - -If the terminal has no special insert mode, but it can insert -characters with a special command, @samp{im} should be defined with a -null value, because the @samp{vi} editor assumes that insertion of a -character is impossible if @samp{im} is not provided. - -New programs should not act like @samp{vi}. They should pay attention -to @samp{im} only if it is defined. - -@item ei -@kindex ei -String of commands to leave insert mode. This capability must be -present if @samp{im} is. - -On a few old terminals the same string is used to enter and exit -insert mode. This string turns insert mode on if it was off, and off -it it was on. You can tell these terminals because the @samp{ei} -string equals the @samp{im} string. If you want to support these -terminals, you must always remember accurately whether insert mode is -in effect. However, these terminals are obsolete, and it is -reasonable to refuse to support them. On all modern terminals, you -can safely output @samp{ei} at any time to ensure that insert mode is -turned off. - -@item ic -@kindex ic -String of commands to insert one character position at the cursor. -The cursor does not move. - -If outputting a graphic character while in insert mode is sufficient -to insert the character, then the @samp{ic} capability should be -defined with a null value. - -If your terminal offers a choice of ways to insert---either use insert -mode or use a special command---then define @samp{im} and do not define -@samp{ic}, since this gives the most efficient operation when several -characters are to be inserted. @emph{Do not} define both strings, for -that means that @emph{both} must be used each time insertion is done. - -@item ip -@kindex ip -String of commands to output following an inserted graphic character -in insert mode. Often it is used just for a padding spec, when padding -is needed after an inserted character (@pxref{Padding}). - -@item IC -@kindex IC -String of commands to insert @var{n} character positions at and after -the cursor. It has the same effect as repeating the @samp{ic} string -and a space, @var{n} times. - -If @samp{IC} is provided, application programs may use it without first -entering insert mode. - -@item mi -@kindex mi -Flag whose presence means it is safe to move the cursor while in insert -mode and assume the terminal remains in insert mode. - -@item in -@kindex in -Flag whose presence means that the terminal distinguishes between -character positions in which space characters have been output and -positions which have been cleared. -@end table - -An application program can assume that the terminal can do character -insertion if @emph{any one of} the capabilities @samp{IC}, @samp{im}, -@samp{ic} or @samp{ip} is provided. - -To insert @var{n} blank character positions, move the cursor to the place -to insert them and follow this algorithm: - -@enumerate -@item -If an @samp{IC} string is provided, output it with parameter @var{n} -and you are finished. Otherwise (or if you don't want to bother to -look for an @samp{IC} string) follow the remaining steps. - -@item -Output the @samp{im} string, if there is one, unless the terminal is -already in insert mode. - -@item -Repeat steps 4 through 6, @var{n} times. - -@item -Output the @samp{ic} string if any. - -@item -Output a space. - -@item -Output the @samp{ip} string if any. - -@item -Output the @samp{ei} string, eventually, to exit insert mode. There -is no need to do this right away. If the @samp{mi} flag is present, -you can move the cursor and the cursor will remain in insert mode; -then you can do more insertion elsewhere without reentering insert -mode. -@end enumerate - -To insert @var{n} graphic characters, position the cursor and follow this -algorithm: - -@enumerate -@item -If an @samp{IC} string is provided, output it with parameter @var{n}, -then output the graphic characters, and you are finished. Otherwise -(or if you don't want to bother to look for an @samp{IC} string) -follow the remaining steps. - -@item -Output the @samp{im} string, if there is one, unless the terminal is -already in insert mode. - -@item -For each character to be output, repeat steps 4 through 6. - -@item -Output the @samp{ic} string if any. - -@item -Output the next graphic character. - -@item -Output the @samp{ip} string if any. - -@item -Output the @samp{ei} string, eventually, to exit insert mode. There -is no need to do this right away. If the @samp{mi} flag is present, -you can move the cursor and the cursor will remain in insert mode; -then you can do more insertion elsewhere without reentering insert -mode. -@end enumerate - -Note that this is not the same as the original Unix termcap specifications -in one respect: it assumes that the @samp{IC} string can be used without -entering insert mode. This is true as far as I know, and it allows you be -able to avoid entering and leaving insert mode, and also to be able to -avoid the inserted-character padding after the characters that go into the -inserted positions. - -Deletion of characters is less complicated; deleting one column is done by -outputting the @samp{dc} string. However, there may be a delete mode that -must be entered with @samp{dm} in order to make @samp{dc} work. - -@table @samp -@item dc -@kindex dc -String of commands to delete one character position at the cursor. If -@samp{dc} is not present, the terminal cannot delete characters. - -@item DC -@kindex DC -String of commands to delete @var{n} characters starting at the cursor. -It has the same effect as repeating the @samp{dc} string @var{n} times. -Any terminal description that has @samp{DC} also has @samp{dc}. - -@item dm -@kindex dm -String of commands to enter delete mode. If not present, there is no -delete mode, and @samp{dc} can be used at any time (assuming there is -a @samp{dc}). - -@item ed -@kindex ed -String of commands to exit delete mode. This must be present if -@samp{dm} is. -@end table - -To delete @var{n} character positions, position the cursor and follow these -steps: - -@enumerate -@item -If the @samp{DC} string is present, output it with parameter @var{n} -and you are finished. Otherwise, follow the remaining steps. - -@item -Output the @samp{dm} string, unless you know the terminal is already -in delete mode. - -@item -Output the @samp{dc} string @var{n} times. - -@item -Output the @samp{ed} string eventually. If the flag capability -@samp{mi} is present, you can move the cursor and do more deletion -without leaving and reentering delete mode. -@end enumerate - -As with the @samp{IC} string, we have departed from the original termcap -specifications by assuming that @samp{DC} works without entering delete -mode even though @samp{dc} would not. - -If the @samp{dm} and @samp{im} capabilities are both present and have the -same value, it means that the terminal has one mode for both insertion and -deletion. It is useful for a program to know this, because then it can do -insertions after deletions, or vice versa, without leaving insert/delete -mode and reentering it. - -@node Standout, Underlining, Insdel Char, Capabilities -@section Standout and Appearance Modes -@cindex appearance modes -@cindex standout -@cindex magic cookie - -@dfn{Appearance modes} are modifications to the ways characters are -displayed. Typical appearance modes include reverse video, dim, bright, -blinking, underlined, invisible, and alternate character set. Each kind of -terminal supports various among these, or perhaps none. - -For each type of terminal, one appearance mode or combination of them that -looks good for highlighted text is chosen as the @dfn{standout mode}. The -capabilities @samp{so} and @samp{se} say how to enter and leave standout -mode. Programs that use appearance modes only to highlight some text -generally use the standout mode so that they can work on as many terminals -as possible. Use of specific appearance modes other than ``underlined'' -and ``alternate character set'' is rare. - -Terminals that implement appearance modes fall into two general classes as -to how they do it. - -In some terminals, the presence or absence of any appearance mode is -recorded separately for each character position. In these terminals, each -graphic character written is given the appearance modes current at the time -it is written, and keeps those modes until it is erased or overwritten. -There are special commands to turn the appearance modes on or off for -characters to be written in the future. - -In other terminals, the change of appearance modes is represented by a -marker that belongs to a certain screen position but affects all following -screen positions until the next marker. These markers are traditionally -called @dfn{magic cookies}. - -The same capabilities (@samp{so}, @samp{se}, @samp{mb} and so on) for -turning appearance modes on and off are used for both magic-cookie -terminals and per-character terminals. On magic cookie terminals, these -give the commands to write the magic cookies. On per-character terminals, -they change the current modes that affect future output and erasure. Some -simple applications can use these commands without knowing whether or not -they work by means of cookies. - -However, a program that maintains and updates a display needs to know -whether the terminal uses magic cookies, and exactly what their effect is. -This information comes from the @samp{sg} capability. - -The @samp{sg} capability is a numeric capability whose presence indicates -that the terminal uses magic cookies for appearance modes. Its value is -the number of character positions that a magic cookie occupies. Usually -the cookie occupies one or more character positions on the screen, and these -character positions are displayed as blank, but in some terminals the -cookie has zero width. - -The @samp{sg} capability describes both the magic cookie to turn standout -on and the cookie to turn it off. This makes the assumption that both -kinds of cookie have the same width on the screen. If that is not true, -the narrower cookie must be ``widened'' with spaces until it has the same -width as the other. - -On some magic cookie terminals, each line always starts with normal -display; in other words, the scope of a magic cookie never extends over -more than one line. But on other terminals, one magic cookie affects all -the lines below it unless explicitly canceled. Termcap does not define any -way to distinguish these two ways magic cookies can work. To be safe, it -is best to put a cookie at the beginning of each line. - -On some per-character terminals, standout mode or other appearance modes -may be canceled by moving the cursor. On others, moving the cursor has no -effect on the state of the appearance modes. The latter class of terminals -are given the flag capability @samp{ms} (``can move in standout''). All -programs that might have occasion to move the cursor while appearance modes -are turned on must check for this flag; if it is not present, they should -reset appearance modes to normal before doing cursor motion. - -A program that has turned on only standout mode should use @samp{se} to -reset the standout mode to normal. A program that has turned on only -alternate character set mode should use @samp{ae} to return it to normal. -If it is possible that any other appearance modes are turned on, use the -@samp{me} capability to return them to normal. - -Note that the commands to turn on one appearance mode, including @samp{so} -and @samp{mb} @dots{} @samp{mr}, if used while some other appearance modes -are turned on, may combine the two modes on some terminals but may turn off -the mode previously enabled on other terminals. This is because some -terminals do not have a command to set or clear one appearance mode without -changing the others. Programs should not attempt to use appearance modes -in combination except with @samp{sa}, and when switching from one single -mode to another should always turn off the previously enabled mode and then -turn on the new desired mode. - -On some old terminals, the @samp{so} and @samp{se} commands may be the same -command, which has the effect of turning standout on if it is off, or off -it is on. It is therefore risky for a program to output extra @samp{se} -commands for good measure. Fortunately, all these terminals are obsolete. - -Programs that update displays in which standout-text may be replaced with -non-standout text must check for the @samp{xs} flag. In a per-character -terminal, this flag says that the only way to remove standout once written is -to clear that portion of the line with the @samp{ce} string or something -even more powerful (@pxref{Clearing}); just writing new characters at those -screen positions will not change the modes in effect there. In a magic -cookie terminal, @samp{xs} says that the only way to remove a cookie is to -clear a portion of the line that includes the cookie; writing a different -cookie at the same position does not work. - -Such programs must also check for the @samp{xt} flag, which means that the -terminal is a Teleray 1061. On this terminal it is impossible to position -the cursor at the front of a magic cookie, so the only two ways to remove a -cookie are (1) to delete the line it is on or (2) to position the cursor at -least one character before it (possibly on a previous line) and output the -@samp{se} string, which on these terminals finds and removes the next -@samp{so} magic cookie on the screen. (It may also be possible to remove a -cookie which is not at the beginning of a line by clearing that line.) The -@samp{xt} capability also has implications for the use of tab characters, -but in that regard it is obsolete (@xref{Cursor Motion}). - -@table @samp -@item so -@kindex so -String of commands to enter standout mode. - -@item se -@kindex se -String of commands to leave standout mode. - -@item sg -@kindex sg -Numeric capability, the width on the screen of the magic cookie. This -capability is absent in terminals that record appearance modes -character by character. - -@item ms -@kindex ms -Flag whose presence means that it is safe to move the cursor while the -appearance modes are not in the normal state. If this flag is absent, -programs should always reset the appearance modes to normal before -moving the cursor. - -@item xs -@kindex xs -Flag whose presence means that the only way to reset appearance modes -already on the screen is to clear to end of line. On a per-character -terminal, you must clear the area where the modes are set. On a magic -cookie terminal, you must clear an area containing the cookie. -See the discussion above. - -@item xt -@kindex xt -Flag whose presence means that the cursor cannot be positioned right -in front of a magic cookie, and that @samp{se} is a command to delete -the next magic cookie following the cursor. See discussion above. - -@item mb -@kindex mb -String of commands to enter blinking mode. - -@item md -@kindex md -String of commands to enter double-bright mode. - -@item mh -@kindex mh -String of commands to enter half-bright mode. - -@item mk -@kindex mk -String of commands to enter invisible mode. - -@item mp -@kindex mp -String of commands to enter protected mode. - -@item mr -@kindex mr -String of commands to enter reverse-video mode. - -@item me -@kindex me -String of commands to turn off all appearance modes, including -standout mode and underline mode. On some terminals it also turns off -alternate character set mode; on others, it may not. This capability -must be present if any of @samp{mb} @dots{} @samp{mr} is present. - -@item as -@kindex as -String of commands to turn on alternate character set mode. This mode -assigns some or all graphic characters an alternate picture on the -screen. There is no standard as to what the alternate pictures look -like. - -@item ae -@kindex ae -String of commands to turn off alternate character set mode. - -@item sa -@kindex sa -String of commands to turn on an arbitrary combination of appearance -modes. It accepts 9 parameters, each of which controls a particular -kind of appearance mode. A parameter should be 1 to turn its appearance -mode on, or zero to turn that mode off. Most terminals do not support -the @samp{sa} capability, even among those that do have various -appearance modes. - -The nine parameters are, in order, @var{standout}, @var{underline}, -@var{reverse}, @var{blink}, @var{half-bright}, @var{double-bright}, -@var{blank}, @var{protect}, @var{alt char set}. -@end table - -@node Underlining, Cursor Visibility, Standout, Capabilities -@section Underlining -@cindex underlining - -Underlining on most terminals is a kind of appearance mode, much like -standout mode. Therefore, it may be implemented using magic cookies or as -a flag in the terminal whose current state affects each character that is -output. @xref{Standout}, for a full explanation. - -The @samp{ug} capability is a numeric capability whose presence indicates -that the terminal uses magic cookies for underlining. Its value is the -number of character positions that a magic cookie for underlining occupies; -it is used for underlining just as @samp{sg} is used for standout. Aside -from the simplest applications, it is impossible to use underlining -correctly without paying attention to the value of @samp{ug}. - -@table @samp -@item us -@kindex us -String of commands to turn on underline mode or to output a magic cookie -to start underlining. - -@item ue -@kindex ue -String of commands to turn off underline mode or to output a magic -cookie to stop underlining. - -@item ug -@kindex ug -Width of magic cookie that represents a change of underline mode; -or missing, if the terminal does not use a magic cookie for this. - -@item ms -@kindex ms -Flag whose presence means that it is safe to move the cursor while the -appearance modes are not in the normal state. Underlining is an -appearance mode. If this flag is absent, programs should always turn -off underlining before moving the cursor. -@end table - -There are two other, older ways of doing underlining: there can be a -command to underline a single character, or the output of @samp{_}, the -ASCII underscore character, as an overstrike could cause a character to be -underlined. New programs need not bother to handle these capabilities -unless the author cares strongly about the obscure terminals which support -them. However, terminal descriptions should provide these capabilities -when appropriate. - -@table @samp -@item uc -@kindex uc -String of commands to underline the character under the cursor, and -move the cursor right. - -@item ul -@kindex ul -Flag whose presence means that the terminal can underline by -overstriking an underscore character (@samp{_}); some terminals can do -this even though they do not support overstriking in general. An -implication of this flag is that when outputting new text to overwrite -old text, underscore characters must be treated specially lest they -underline the old text instead. -@end table - -@node Cursor Visibility, Bell, Underlining, Capabilities -@section Cursor Visibility -@cindex visibility - -Some terminals have the ability to make the cursor invisible, or to enhance -it. Enhancing the cursor is often done by programs that plan to use the -cursor to indicate to the user a position of interest that may be anywhere -on the screen---for example, the Emacs editor enhances the cursor on entry. -Such programs should always restore the cursor to normal on exit. - -@table @samp -@item vs -@kindex vs -String of commands to enhance the cursor. - -@item vi -@kindex vi -String of commands to make the cursor invisible. - -@item ve -@kindex ve -String of commands to return the cursor to normal. -@end table - -If you define either @samp{vs} or @samp{vi}, you must also define @samp{ve}. - -@node Bell, Keypad, Cursor Visibility, Capabilities -@section Bell -@cindex bell -@cindex visible bell - -Here we describe commands to make the terminal ask for the user to pay -attention to it. - -@table @samp -@item bl -@kindex bl -String of commands to cause the terminal to make an audible sound. If -this capability is absent, the terminal has no way to make a suitable -sound. - -@item vb -@kindex vb -String of commands to cause the screen to flash to attract attention -(``visible bell''). If this capability is absent, the terminal has no -way to do such a thing. -@end table - -@node Keypad, Meta Key, Bell, Capabilities -@section Keypad and Function Keys - -Many terminals have arrow and function keys that transmit specific -character sequences to the computer. Since the precise sequences used -depend on the terminal, termcap defines capabilities used to say what the -sequences are. Unlike most termcap string-valued capabilities, these are -not strings of commands to be sent to the terminal, rather strings that -are received from the terminal. - -Programs that expect to use keypad keys should check, initially, for a -@samp{ks} capability and send it, to make the keypad actually transmit. -Such programs should also send the @samp{ke} string when exiting. - -@table @asis -@item @samp{ks} -@kindex ka@dots{}ku -String of commands to make the keypad keys transmit. If this -capability is not provided, but the others in this section are, -programs may assume that the keypad keys always transmit. - -@item @samp{ke} -String of commands to make the keypad keys work locally. This -capability is provided only if @samp{ks} is. - -@item @samp{kl} -String of input characters sent by typing the left-arrow key. If this -capability is missing, you cannot expect the terminal to have a -left-arrow key that transmits anything to the computer. - -@item @samp{kr} -String of input characters sent by typing the right-arrow key. - -@item @samp{ku} -String of input characters sent by typing the up-arrow key. - -@item @samp{kd} -String of input characters sent by typing the down-arrow key. - -@item @samp{kh} -String of input characters sent by typing the ``home-position'' key. - -@item @samp{K1} @dots{} @samp{K5} -@kindex K1@dots{}K5 -Strings of input characters sent by the five other keys in a 3-by-3 -array that includes the arrow keys, if the keyboard has such a 3-by-3 -array. Note that one of these keys may be the ``home-position'' key, -in which case one of these capabilities will have the same value as -the @samp{kh} key. - -@item @samp{k0} -String of input characters sent by function key 10 (or 0, if the terminal -has one labeled 0). - -@item @samp{k1} @dots{} @samp{k9} -@kindex k1@dots{}k9 -Strings of input characters sent by function keys 1 through 9, -provided for those function keys that exist. - -@item @samp{kn} -Number: the number of numbered function keys, if there are more than -10. - -@item @samp{l0} @dots{} @samp{l9} -@kindex l0@dots{}l9 -Strings which are the labels appearing on the keyboard on the keys -described by the capabilities @samp{k0} @dots{} @samp{l9}. These -capabilities should be left undefined if the labels are @samp{f0} or -@samp{f10} and @samp{f1} @dots{} @samp{f9}.@refill - -@item @samp{kH} -@kindex kA@dots{}kT -String of input characters sent by the ``home down'' key, if there is -one. - -@item @samp{kb} -String of input characters sent by the ``backspace'' key, if there is -one. - -@item @samp{ka} -String of input characters sent by the ``clear all tabs'' key, if there -is one. - -@item @samp{kt} -String of input characters sent by the ``clear tab stop this column'' -key, if there is one. - -@item @samp{kC} -String of input characters sent by the ``clear screen'' key, if there is -one. - -@item @samp{kD} -String of input characters sent by the ``delete character'' key, if -there is one. - -@item @samp{kL} -String of input characters sent by the ``delete line'' key, if there is -one. - -@item @samp{kM} -String of input characters sent by the ``exit insert mode'' key, if -there is one. - -@item @samp{kE} -String of input characters sent by the ``clear to end of line'' key, if -there is one. - -@item @samp{kS} -String of input characters sent by the ``clear to end of screen'' key, -if there is one. - -@item @samp{kI} -String of input characters sent by the ``insert character'' or ``enter -insert mode'' key, if there is one. - -@item @samp{kA} -String of input characters sent by the ``insert line'' key, if there is -one. - -@item @samp{kN} -String of input characters sent by the ``next page'' key, if there is -one. - -@item @samp{kP} -String of input characters sent by the ``previous page'' key, if there is -one. - -@item @samp{kF} -String of input characters sent by the ``scroll forward'' key, if there -is one. - -@item @samp{kR} -String of input characters sent by the ``scroll reverse'' key, if there -is one. - -@item @samp{kT} -String of input characters sent by the ``set tab stop in this column'' -key, if there is one. - -@item @samp{ko} -String listing the other function keys the terminal has. This is a -very obsolete way of describing the same information found in the -@samp{kH} @dots{} @samp{kT} keys. The string contains a list of -two-character termcap capability names, separated by commas. The -meaning is that for each capability name listed, the terminal has a -key which sends the string which is the value of that capability. For -example, the value @samp{:ko=cl,ll,sf,sr:} says that the terminal has -four function keys which mean ``clear screen'', ``home down'', -``scroll forward'' and ``scroll reverse''.@refill -@end table - -@node Meta Key, Initialization, Keypad, Capabilities -@section Meta Key - -@cindex meta key -A Meta key is a key on the keyboard that modifies each character you type -by controlling the 0200 bit. This bit is on if and only if the Meta key is -held down when the character is typed. Characters typed using the Meta key -are called Meta characters. Emacs uses Meta characters as editing -commands. - -@table @samp -@item km -@kindex km -Flag whose presence means that the terminal has a Meta key. - -@item mm -@kindex mm -String of commands to enable the functioning of the Meta key. - -@item mo -@kindex mo -String of commands to disable the functioning of the Meta key. -@end table - -If the terminal has @samp{km} but does not have @samp{mm} and @samp{mo}, it -means that the Meta key always functions. If it has @samp{mm} and -@samp{mo}, it means that the Meta key can be turned on or off. Send the -@samp{mm} string to turn it on, and the @samp{mo} string to turn it off. -I do not know why one would ever not want it to be on. - -@node Initialization, Pad Specs, Meta Key, Capabilities -@section Initialization -@cindex reset -@cindex initialization -@cindex tab stops - -@table @samp -@item ti -@kindex ti -String of commands to put the terminal into whatever special modes are -needed or appropriate for programs that move the cursor -nonsequentially around the screen. Programs that use termcap to do -full-screen display should output this string when they start up. - -@item te -@kindex te -String of commands to undo what is done by the @samp{ti} string. -Programs that output the @samp{ti} string on entry should output this -string when they exit. - -@item is -@kindex is -String of commands to initialize the terminal for each login session. - -@item if -@kindex if -String which is the name of a file containing the string of commands -to initialize the terminal for each session of use. Normally @samp{is} -and @samp{if} are not both used. - -@item i1 -@itemx i3 -@kindex i1 -@kindex i3 -Two more strings of commands to initialize the terminal for each login -session. The @samp{i1} string (if defined) is output before @samp{is} -or @samp{if}, and the @samp{i3} string (if defined) is output after. - -The reason for having three separate initialization strings is to make -it easier to define a group of related terminal types with slightly -different initializations. Define two or three of the strings in the -basic type; then the other types can override one or two of the -strings. - -@item rs -@kindex rs -String of commands to reset the terminal from any strange mode it may -be in. Normally this includes the @samp{is} string (or other commands -with the same effects) and more. What would go in the @samp{rs} -string but not in the @samp{is} string are annoying or slow commands -to bring the terminal back from strange modes that nobody would -normally use. - -@item it -@kindex it -Numeric value, the initial spacing between hardware tab stop columns -when the terminal is powered up. Programs to initialize the terminal -can use this to decide whether there is a need to set the tab stops. -If the initial width is 8, well and good; if it is not 8, then the -tab stops should be set; if they cannot be set, the kernel is told -to convert tabs to spaces, and other programs will observe this and do -likewise. - -@item ct -@kindex ct -String of commands to clear all tab stops. - -@item st -@kindex st -String of commands to set tab stop at current cursor column on all -lines. - -@item NF -@kindex NF -Flag whose presence means that the terminal does not support XON/XOFF -flow control. Programs should not send XON (@kbd{C-q}) or XOFF -(@kbd{C-s}) characters to the terminal. -@end table - -@node Pad Specs, Status Line, Initialization, Capabilities -@section Padding Capabilities -@cindex padding - -There are two terminal capabilities that exist just to explain the proper -way to obey the padding specifications in all the command string -capabilities. One, @samp{pc}, must be obeyed by all termcap-using -programs. - -@table @samp -@item pb -@kindex pb -Numeric value, the lowest baud rate at which padding is actually -needed. Programs may check this and refrain from doing any padding at -lower speeds. - -@item pc -@kindex pc -String of commands for padding. The first character of this string is -to be used as the pad character, instead of using null characters for -padding. If @samp{pc} is not provided, use null characters. Every -program that uses termcap must look up this capability and use it to -set the variable @code{PC} that is used by @code{tputs}. -@xref{Padding}. -@end table - -Some termcap capabilities exist just to specify the amount of padding that -the kernel should give to cursor motion commands used in ordinary -sequential output. - -@table @samp -@item dC -@kindex dC -Numeric value, the number of msec of padding needed for the -carriage-return character. - -@item dN -@kindex dN -Numeric value, the number of msec of padding needed for the newline -(linefeed) character. - -@item dB -@kindex dB -Numeric value, the number of msec of padding needed for the backspace -character. - -@item dF -@kindex dF -Numeric value, the number of msec of padding needed for the formfeed -character. - -@item dT -@kindex dT -Numeric value, the number of msec of padding needed for the tab -character. -@end table - -In some systems, the kernel uses the above capabilities; in other systems, -the kernel uses the paddings specified in the string capabilities -@samp{cr}, @samp{sf}, @samp{le}, @samp{ff} and @samp{ta}. Descriptions of -terminals which require such padding should contain the @samp{dC} @dots{} -@samp{dT} capabilities and also specify the appropriate padding in the -corresponding string capabilities. Since no modern terminals require -padding for ordinary sequential output, you probably won't need to do -either of these things. - -@node Status Line, Half-Line, Pad Specs, Capabilities -@section Status Line - -@cindex status line -A @dfn{status line} is a line on the terminal that is not used for ordinary -display output but instead used for a special message. The intended use is -for a continuously updated description of what the user's program is doing, -and that is where the name ``status line'' comes from, but in fact it could -be used for anything. The distinguishing characteristic of a status line -is that ordinary output to the terminal does not affect it; it changes only -if the special status line commands of this section are used. - -@table @samp -@item hs -@kindex hs -Flag whose presence means that the terminal has a status line. If a -terminal description specifies that there is a status line, it must -provide the @samp{ts} and @samp{fs} capabilities. - -@item ts -@kindex ts -String of commands to move the terminal cursor into the status line. -Usually these commands must specifically record the old cursor -position for the sake of the @samp{fs} string. - -@item fs -@kindex fs -String of commands to move the cursor back from the status line to its -previous position (outside the status line). - -@item es -@kindex es -Flag whose presence means that other display commands work while -writing the status line. In other words, one can clear parts of it, -insert or delete characters, move the cursor within it using @samp{ch} -if there is a @samp{ch} capability, enter and leave standout mode, and -so on. - -@item ds -@kindex ds -String of commands to disable the display of the status line. This -may be absent, if there is no way to disable the status line display. - -@item ws -@kindex ws -Numeric value, the width of the status line. If this capability is -absent in a terminal that has a status line, it means the status line -is the same width as the other lines. - -Note that the value of @samp{ws} is sometimes as small as 8. -@end table - -@node Half-Line, Printer, Status Line, Capabilities -@section Half-Line Motion - -Some terminals have commands for moving the cursor vertically by half-lines, -useful for outputting subscripts and superscripts. Mostly it is hardcopy -terminals that have such features. - -@table @samp -@item hu -@kindex hu -String of commands to move the cursor up half a line. If the terminal -is a display, it is your responsibility to avoid moving up past the -top line; however, most likely the terminal that supports this is a -hardcopy terminal and there is nothing to be concerned about. - -@item hd -@kindex hd -String of commands to move the cursor down half a line. If the -terminal is a display, it is your responsibility to avoid moving down -past the bottom line, etc. -@end table - -@node Printer, , Half-Line, Capabilities -@section Controlling Printers Attached to Terminals -@cindex printer - -Some terminals have attached hardcopy printer ports. They may be able to -copy the screen contents to the printer; they may also be able to redirect -output to the printer. Termcap does not have anything to tell the program -whether the redirected output appears also on the screen; it does on some -terminals but not all. - -@table @samp -@item ps -@kindex ps -String of commands to cause the contents of the screen to be printed. -If it is absent, the screen contents cannot be printed. - -@item po -@kindex po -String of commands to redirect further output to the printer. - -@item pf -@kindex pf -String of commands to terminate redirection of output to the printer. -This capability must be present in the description if @samp{po} is. - -@item pO -@kindex pO -String of commands to redirect output to the printer for next @var{n} -characters of output, regardless of what they are. Redirection will -end automatically after @var{n} characters of further output. Until -then, nothing that is output can end redirection, not even the -@samp{pf} string if there is one. The number @var{n} should not be -more than 255. - -One use of this capability is to send non-text byte sequences (such as -bit-maps) to the printer. -@end table - -Most terminals with printers do not support all of @samp{ps}, @samp{po} and -@samp{pO}; any one or two of them may be supported. To make a program that -can send output to all kinds of printers, it is necessary to check for all -three of these capabilities, choose the most convenient of the ones that -are provided, and use it in its own appropriate fashion. - -@node Summary, Var Index, Capabilities, Top -@chapter Summary of Capability Names - -Here are all the terminal capability names in alphabetical order -with a brief description of each. For cross references to their definitions, -see the index of capability names (@pxref{Cap Index}). - -@table @samp -@item ae -String to turn off alternate character set mode. -@item al -String to insert a blank line before the cursor. -@item AL -String to insert @var{n} blank lines before the cursor. -@item am -Flag: output to last column wraps cursor to next line. -@item as -String to turn on alternate character set mode.like. -@item bc -Very obsolete alternative name for the @samp{le} capability. -@item bl -String to sound the bell. -@item bs -Obsolete flag: ASCII backspace may be used for leftward motion. -@item bt -String to move the cursor left to the previous hardware tab stop column. -@item bw -Flag: @samp{le} at left margin wraps to end of previous line. -@item CC -String to change terminal's command character. -@item cd -String to clear the line the cursor is on, and following lines. -@item ce -String to clear from the cursor to the end of the line. -@item ch -String to position the cursor at column @var{c} in the same line. -@item cl -String to clear the entire screen and put cursor at upper left corner. -@item cm -String to position the cursor at line @var{l}, column @var{c}. -@item CM -String to position the cursor at line @var{l}, column -@var{c}, relative to display memory. -@item co -Number: width of the screen. -@item cr -String to move cursor sideways to left margin. -@item cs -String to set the scroll region. -@item cS -Alternate form of string to set the scroll region. -@item ct -String to clear all tab stops. -@item cv -String to position the cursor at line @var{l} in the same column. -@item da -Flag: data scrolled off top of screen may be scrolled back. -@item db -Flag: data scrolled off bottom of screen may be scrolled back. -@item dB -Obsolete number: msec of padding needed for the backspace character. -@item dc -String to delete one character position at the cursor. -@item dC -Obsolete number: msec of padding needed for the carriage-return character. -@item DC -String to delete @var{n} characters starting at the cursor. -@item dF -Obsolete number: msec of padding needed for the formfeed character. -@item dl -String to delete the line the cursor is on. -@item DL -String to delete @var{n} lines starting with the cursor's line. -@item dm -String to enter delete mode. -@item dN -Obsolete number: msec of padding needed for the newline character. -@item do -String to move the cursor vertically down one line. -@item DO -String to move cursor vertically down @var{n} lines. -@item ds -String to disable the display of the status line. -@item dT -Obsolete number: msec of padding needed for the tab character. -@item ec -String of commands to clear @var{n} characters at cursor. -@item ed -String to exit delete mode. -@item ei -String to leave insert mode. -@item eo -Flag: output of a space can erase an overstrike. -@item es -Flag: other display commands work while writing the status line. -@item ff -String to advance to the next page, for a hardcopy terminal. -@item fs -String to move the cursor back from the status line to its -previous position (outside the status line). -@item gn -Flag: this terminal type is generic, not real. -@item hc -Flag: hardcopy terminal. -@item hd -String to move the cursor down half a line. -@item ho -String to position cursor at upper left corner. -@item hs -Flag: the terminal has a status line. -@item hu -String to move the cursor up half a line. -@item hz -Flag: terminal cannot accept @samp{~} as output. -@item i1 -String to initialize the terminal for each login session. -@item i3 -String to initialize the terminal for each login session. -@item ic -String to insert one character position at the cursor. -@item IC -String to insert @var{n} character positions at the cursor. -@item if -String naming a file of commands to initialize the terminal. -@item im -String to enter insert mode. -@item in -Flag: outputting a space is different from moving over empty positions. -@item ip -String to output following an inserted character in insert mode. -@item is -String to initialize the terminal for each login session. -@item it -Number: initial spacing between hardware tab stop columns. -@item k0 -String of input sent by function key 0 or 10. -@item k1 @dots{} k9 -Strings of input sent by function keys 1 through 9. -@item K1 @dots{} K5 -Strings sent by the five other keys in 3-by-3 array with arrows. -@item ka -String of input sent by the ``clear all tabs'' key. -@item kA -String of input sent by the ``insert line'' key. -@item kb -String of input sent by the ``backspace'' key. -@item kC -String of input sent by the ``clear screen'' key. -@item kd -String of input sent by typing the down-arrow key. -@item kD -String of input sent by the ``delete character'' key. -@item ke -String to make the function keys work locally. -@item kE -String of input sent by the ``clear to end of line'' key. -@item kF -String of input sent by the ``scroll forward'' key. -@item kh -String of input sent by typing the ``home-position'' key. -@item kH -String of input sent by the ``home down'' key. -@item kI -String of input sent by the ``insert character'' or ``enter -insert mode'' key. -@item kl -String of input sent by typing the left-arrow key. -@item kL -String of input sent by the ``delete line'' key. -@item km -Flag: the terminal has a Meta key. -@item kM -String of input sent by the ``exit insert mode'' key. -@item kn -Numeric value, the number of numbered function keys. -@item kN -String of input sent by the ``next page'' key. -@item ko -Very obsolete string listing the terminal's named function keys. -@item kP -String of input sent by the ``previous page'' key. -@item kr -String of input sent by typing the right-arrow key. -@item kR -String of input sent by the ``scroll reverse'' key. -@item ks -String to make the function keys transmit. -@item kS -String of input sent by the ``clear to end of screen'' key. -@item kt -String of input sent by the ``clear tab stop this column'' key. -@item kT -String of input sent by the ``set tab stop in this column'' key. -@item ku -String of input sent by typing the up-arrow key. -@item l0 -String on keyboard labelling function key 0 or 10. -@item l1 @dots{} l9 -Strings on keyboard labelling function keys 1 through 9. -@item le -String to move the cursor left one column. -@item LE -String to move cursor left @var{n} columns. -@item li -Number: height of the screen. -@item ll -String to position cursor at lower left corner. -@item lm -Number: lines of display memory. -@item LP -Flag: writing to last column of last line will not scroll. -@item mb -String to enter blinking mode. -@item md -String to enter double-bright mode. -@item me -String to turn off all appearance modes -@item mh -String to enter half-bright mode. -@item mi -Flag: cursor motion in insert mode is safe. -@item mk -String to enter invisible mode. -@item mm -String to enable the functioning of the Meta key. -@item mo -String to disable the functioning of the Meta key. -@item mp -String to enter protected mode. -@item mr -String to enter reverse-video mode. -@item ms -Flag: cursor motion in standout mode is safe. -@item nc -Obsolete flag: do not use ASCII carriage-return on this terminal. -@item nd -String to move the cursor right one column. -@item NF -Flag: do not use XON/XOFF flow control. -@item nl -Obsolete alternative name for the @samp{do} and @samp{sf} capabilities. -@item ns -Flag: the terminal does not normally scroll for sequential output. -@item nw -String to move to start of next line, possibly clearing rest of old line. -@item os -Flag: terminal can overstrike. -@item pb -Number: the lowest baud rate at which padding is actually needed. -@item pc -String containing character for padding. -@item pf -String to terminate redirection of output to the printer. -@item po -String to redirect further output to the printer. -@item pO -String to redirect @var{n} characters ofoutput to the printer. -@item ps -String to print the screen on the attached printer. -@item rc -String to move to last saved cursor position. -@item RI -String to move cursor right @var{n} columns. -@item rp -String to output character @var{c} repeated @var{n} times. -@item rs -String to reset the terminal from any strange modes. -@item sa -String to turn on an arbitrary combination of appearance modes. -@item sc -String to save the current cursor position. -@item se -String to leave standout mode. -@item sf -String to scroll the screen one line up. -@item SF -String to scroll the screen @var{n} lines up. -@item sg -Number: width of magic standout cookie. Absent if magic cookies are -not used. -@item so -String to enter standout mode. -@item sr -String to scroll the screen one line down. -@item SR -String to scroll the screen @var{n} line down. -@item st -String to set tab stop at current cursor column on all lines. -programs. -@item ta -String to move the cursor right to the next hardware tab stop column. -@item te -String to return terminal to settings for sequential output. -@item ti -String to initialize terminal for random cursor motion. -@item ts -String to move the terminal cursor into the status line. -@item uc -String to underline one character and move cursor right. -@item ue -String to turn off underline mode -@item ug -Number: width of underlining magic cookie. Absent if underlining -doesn't use magic cookies. -@item ul -Flag: underline by overstriking with an underscore. -@item up -String to move the cursor vertically up one line. -@item UP -String to move cursor vertically up @var{n} lines. -@item us -String to turn on underline mode -@item vb -String to make the screen flash. -@item ve -String to return the cursor to normal. -@item vi -String to make the cursor invisible. -@item vs -String to enhance the cursor. -@item wi -String to set the terminal output screen window. -@item ws -Number: the width of the status line. -@item xb -Flag: superbee terminal. -@item xn -Flag: cursor wraps in a strange way. -@item xs -Flag: clearing a line is the only way to clear the appearance modes of -positions in that line (or, only way to remove magic cookies on that -line). -@item xt -Flag: Teleray 1061; several strange characteristics. -@end table - -@node Var Index, Cap Index, Summary, Top -@unnumbered Variable and Function Index - -@printindex fn - -@node Cap Index, Index, Var Index, Top -@unnumbered Capability Index - -@printindex ky - -@node Index, , Cap Index, Top -@unnumbered Concept Index - -@printindex cp - -@contents -@bye - diff --git a/src/libs/termcap/texinfo.tex b/src/libs/termcap/texinfo.tex deleted file mode 100644 index c49af9f4ed..0000000000 --- a/src/libs/termcap/texinfo.tex +++ /dev/null @@ -1,5992 +0,0 @@ -% texinfo.tex -- TeX macros to handle Texinfo files. -% -% Load plain if necessary, i.e., if running under initex. -\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi -% -\def\texinfoversion{1999-09-25.10} -% -% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 -% Free Software Foundation, Inc. -% -% This texinfo.tex file is free software; you can redistribute it and/or -% modify it under the terms of the GNU General Public License as -% published by the Free Software Foundation; either version 2, or (at -% your option) any later version. -% -% This texinfo.tex file is distributed in the hope that 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 texinfo.tex file; see the file COPYING. If not, write -% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -% Boston, MA 02111-1307, USA. -% -% In other words, you are welcome to use, share and improve this program. -% You are forbidden to forbid anyone else to use, share and improve -% what you give them. Help stamp out software-hoarding! -% -% Please try the latest version of texinfo.tex before submitting bug -% reports; you can get the latest version from: -% ftp://ftp.gnu.org/gnu/texinfo.tex -% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) -% ftp://texinfo.org/tex/texinfo.tex -% ftp://us.ctan.org/macros/texinfo/texinfo.tex -% (and all CTAN mirrors, finger ctan@us.ctan.org for a list). -% /home/gd/gnu/doc/texinfo.tex on the GNU machines. -% The texinfo.tex in any given Texinfo distribution could well be out -% of date, so if that's what you're using, please check. -% Texinfo has a small home page at http://texinfo.org/. -% -% Send bug reports to bug-texinfo@gnu.org. Please include including a -% complete document in each bug report with which we can reproduce the -% problem. Patches are, of course, greatly appreciated. -% -% To process a Texinfo manual with TeX, it's most reliable to use the -% texi2dvi shell script that comes with the distribution. For a simple -% manual foo.texi, however, you can get away with this: -% tex foo.texi -% texindex foo.?? -% tex foo.texi -% tex foo.texi -% dvips foo.dvi -o # or whatever, to process the dvi file; this makes foo.ps. -% The extra runs of TeX get the cross-reference information correct. -% Sometimes one run after texindex suffices, and sometimes you need more -% than two; texi2dvi does it as many times as necessary. -% -% It is possible to adapt texinfo.tex for other languages. You can get -% the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/. - -\message{Loading texinfo [version \texinfoversion]:} - -% If in a .fmt file, print the version number -% and turn on active characters that we couldn't do earlier because -% they might have appeared in the input file name. -\everyjob{\message{[Texinfo version \texinfoversion]}% - \catcode`+=\active \catcode`\_=\active} - -% Save some parts of plain tex whose names we will redefine. -\let\ptexb=\b -\let\ptexbullet=\bullet -\let\ptexc=\c -\let\ptexcomma=\, -\let\ptexdot=\. -\let\ptexdots=\dots -\let\ptexend=\end -\let\ptexequiv=\equiv -\let\ptexexclam=\! -\let\ptexi=\i -\let\ptexlbrace=\{ -\let\ptexrbrace=\} -\let\ptexstar=\* -\let\ptext=\t - -% We never want plain's outer \+ definition in Texinfo. -% For @tex, we can use \tabalign. -\let\+ = \relax - -\message{Basics,} -\chardef\other=12 - -% If this character appears in an error message or help string, it -% starts a new line in the output. -\newlinechar = `^^J - -% Set up fixed words for English if not already set. -\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi -\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi -\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi -\ifx\putwordin\undefined \gdef\putwordin{in}\fi -\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi -\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi -\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi -\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi -\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi -\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi -\ifx\putwordof\undefined \gdef\putwordof{of}\fi -\ifx\putwordon\undefined \gdef\putwordon{on}\fi -\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi -\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi -\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi -\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi -\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi -\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi -\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi -% -\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi -\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi -\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi -\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi -\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi -\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi -\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi -\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi -\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi -\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi -\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi -\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi -% -\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi -\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi -\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi -\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi -\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi -\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi -\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi - -% Ignore a token. -% -\def\gobble#1{} - -\hyphenation{ap-pen-dix} -\hyphenation{mini-buf-fer mini-buf-fers} -\hyphenation{eshell} -\hyphenation{white-space} - -% Margin to add to right of even pages, to left of odd pages. -\newdimen \bindingoffset -\newdimen \normaloffset -\newdimen\pagewidth \newdimen\pageheight - -% Sometimes it is convenient to have everything in the transcript file -% and nothing on the terminal. We don't just call \tracingall here, -% since that produces some useless output on the terminal. -% -\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% -\ifx\eTeXversion\undefined -\def\loggingall{\tracingcommands2 \tracingstats2 - \tracingpages1 \tracingoutput1 \tracinglostchars1 - \tracingmacros2 \tracingparagraphs1 \tracingrestores1 - \showboxbreadth\maxdimen\showboxdepth\maxdimen -}% -\else -\def\loggingall{\tracingcommands3 \tracingstats2 - \tracingpages1 \tracingoutput1 \tracinglostchars1 - \tracingmacros2 \tracingparagraphs1 \tracingrestores1 - \tracingscantokens1 \tracingassigns1 \tracingifs1 - \tracinggroups1 \tracingnesting2 - \showboxbreadth\maxdimen\showboxdepth\maxdimen -}% -\fi - -% For @cropmarks command. -% Do @cropmarks to get crop marks. -% -\newif\ifcropmarks -\let\cropmarks = \cropmarkstrue -% -% Dimensions to add cropmarks at corners. -% Added by P. A. MacKay, 12 Nov. 1986 -% -\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines -\newdimen\cornerlong \cornerlong=1pc -\newdimen\cornerthick \cornerthick=.3pt -\newdimen\topandbottommargin \topandbottommargin=.75in - -% Main output routine. -\chardef\PAGE = 255 -\output = {\onepageout{\pagecontents\PAGE}} - -\newbox\headlinebox -\newbox\footlinebox - -% \onepageout takes a vbox as an argument. Note that \pagecontents -% does insertions, but you have to call it yourself. -\def\onepageout#1{% - \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi - % - \ifodd\pageno \advance\hoffset by \bindingoffset - \else \advance\hoffset by -\bindingoffset\fi - % - % Do this outside of the \shipout so @code etc. will be expanded in - % the headline as they should be, not taken literally (outputting ''code). - \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% - \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% - % - {% - % Have to do this stuff outside the \shipout because we want it to - % take effect in \write's, yet the group defined by the \vbox ends - % before the \shipout runs. - % - \escapechar = `\\ % use backslash in output files. - \indexdummies % don't expand commands in the output. - \normalturnoffactive % \ in index entries must not stay \, e.g., if - % the page break happens to be in the middle of an example. - \shipout\vbox{% - \ifcropmarks \vbox to \outervsize\bgroup - \hsize = \outerhsize - \vskip-\topandbottommargin - \vtop to0pt{% - \line{\ewtop\hfil\ewtop}% - \nointerlineskip - \line{% - \vbox{\moveleft\cornerthick\nstop}% - \hfill - \vbox{\moveright\cornerthick\nstop}% - }% - \vss}% - \vskip\topandbottommargin - \line\bgroup - \hfil % center the page within the outer (page) hsize. - \ifodd\pageno\hskip\bindingoffset\fi - \vbox\bgroup - \fi - % - \unvbox\headlinebox - \pagebody{#1}% - \ifdim\ht\footlinebox > 0pt - % Only leave this space if the footline is nonempty. - % (We lessened \vsize for it in \oddfootingxxx.) - % The \baselineskip=24pt in plain's \makefootline has no effect. - \vskip 2\baselineskip - \unvbox\footlinebox - \fi - % - \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi - % - \ifcropmarks - \egroup % end of \vbox\bgroup - \hfil\egroup % end of (centering) \line\bgroup - \vskip\topandbottommargin plus1fill minus1fill - \boxmaxdepth = \cornerthick - \vbox to0pt{\vss - \line{% - \vbox{\moveleft\cornerthick\nsbot}% - \hfill - \vbox{\moveright\cornerthick\nsbot}% - }% - \nointerlineskip - \line{\ewbot\hfil\ewbot}% - }% - \egroup % \vbox from first cropmarks clause - \fi - }% end of \shipout\vbox - }% end of group with \turnoffactive - \advancepageno - \ifnum\outputpenalty>-20000 \else\dosupereject\fi -} - -\newinsert\margin \dimen\margin=\maxdimen - -\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} -{\catcode`\@ =11 -\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi -% marginal hacks, juha@viisa.uucp (Juha Takala) -\ifvoid\margin\else % marginal info is present - \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi -\dimen@=\dp#1 \unvbox#1 -\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi -\ifr@ggedbottom \kern-\dimen@ \vfil \fi} -} - -% Here are the rules for the cropmarks. Note that they are -% offset so that the space between them is truly \outerhsize or \outervsize -% (P. A. MacKay, 12 November, 1986) -% -\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} -\def\nstop{\vbox - {\hrule height\cornerthick depth\cornerlong width\cornerthick}} -\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} -\def\nsbot{\vbox - {\hrule height\cornerlong depth\cornerthick width\cornerthick}} - -% Parse an argument, then pass it to #1. The argument is the rest of -% the input line (except we remove a trailing comment). #1 should be a -% macro which expects an ordinary undelimited TeX argument. -% -\def\parsearg#1{% - \let\next = #1% - \begingroup - \obeylines - \futurelet\temp\parseargx -} - -% If the next token is an obeyed space (from an @example environment or -% the like), remove it and recurse. Otherwise, we're done. -\def\parseargx{% - % \obeyedspace is defined far below, after the definition of \sepspaces. - \ifx\obeyedspace\temp - \expandafter\parseargdiscardspace - \else - \expandafter\parseargline - \fi -} - -% Remove a single space (as the delimiter token to the macro call). -{\obeyspaces % - \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} - -{\obeylines % - \gdef\parseargline#1^^M{% - \endgroup % End of the group started in \parsearg. - % - % First remove any @c comment, then any @comment. - % Result of each macro is put in \toks0. - \argremovec #1\c\relax % - \expandafter\argremovecomment \the\toks0 \comment\relax % - % - % Call the caller's macro, saved as \next in \parsearg. - \expandafter\next\expandafter{\the\toks0}% - }% -} - -% Since all \c{,omment} does is throw away the argument, we can let TeX -% do that for us. The \relax here is matched by the \relax in the call -% in \parseargline; it could be more or less anything, its purpose is -% just to delimit the argument to the \c. -\def\argremovec#1\c#2\relax{\toks0 = {#1}} -\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} - -% \argremovec{,omment} might leave us with trailing spaces, though; e.g., -% @end itemize @c foo -% will have two active spaces as part of the argument with the -% `itemize'. Here we remove all active spaces from #1, and assign the -% result to \toks0. -% -% This loses if there are any *other* active characters besides spaces -% in the argument -- _ ^ +, for example -- since they get expanded. -% Fortunately, Texinfo does not define any such commands. (If it ever -% does, the catcode of the characters in questionwill have to be changed -% here.) But this means we cannot call \removeactivespaces as part of -% \argremovec{,omment}, since @c uses \parsearg, and thus the argument -% that \parsearg gets might well have any character at all in it. -% -\def\removeactivespaces#1{% - \begingroup - \ignoreactivespaces - \edef\temp{#1}% - \global\toks0 = \expandafter{\temp}% - \endgroup -} - -% Change the active space to expand to nothing. -% -\begingroup - \obeyspaces - \gdef\ignoreactivespaces{\obeyspaces\let =\empty} -\endgroup - - -\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} - -%% These are used to keep @begin/@end levels from running away -%% Call \inENV within environments (after a \begingroup) -\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} -\def\ENVcheck{% -\ifENV\errmessage{Still within an environment; press RETURN to continue} -\endgroup\fi} % This is not perfect, but it should reduce lossage - -% @begin foo is the same as @foo, for now. -\newhelp\EMsimple{Press RETURN to continue.} - -\outer\def\begin{\parsearg\beginxxx} - -\def\beginxxx #1{% -\expandafter\ifx\csname #1\endcsname\relax -{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else -\csname #1\endcsname\fi} - -% @end foo executes the definition of \Efoo. -% -\def\end{\parsearg\endxxx} -\def\endxxx #1{% - \removeactivespaces{#1}% - \edef\endthing{\the\toks0}% - % - \expandafter\ifx\csname E\endthing\endcsname\relax - \expandafter\ifx\csname \endthing\endcsname\relax - % There's no \foo, i.e., no ``environment'' foo. - \errhelp = \EMsimple - \errmessage{Undefined command `@end \endthing'}% - \else - \unmatchedenderror\endthing - \fi - \else - % Everything's ok; the right environment has been started. - \csname E\endthing\endcsname - \fi -} - -% There is an environment #1, but it hasn't been started. Give an error. -% -\def\unmatchedenderror#1{% - \errhelp = \EMsimple - \errmessage{This `@end #1' doesn't have a matching `@#1'}% -} - -% Define the control sequence \E#1 to give an unmatched @end error. -% -\def\defineunmatchedend#1{% - \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% -} - - -% Single-spacing is done by various environments (specifically, in -% \nonfillstart and \quotations). -\newskip\singlespaceskip \singlespaceskip = 12.5pt -\def\singlespace{% - % Why was this kern here? It messes up equalizing space above and below - % environments. --karl, 6may93 - %{\advance \baselineskip by -\singlespaceskip - %\kern \baselineskip}% - \setleading \singlespaceskip -} - -%% Simple single-character @ commands - -% @@ prints an @ -% Kludge this until the fonts are right (grr). -\def\@{{\tt\char64}} - -% This is turned off because it was never documented -% and you can use @w{...} around a quote to suppress ligatures. -%% Define @` and @' to be the same as ` and ' -%% but suppressing ligatures. -%\def\`{{`}} -%\def\'{{'}} - -% Used to generate quoted braces. -\def\mylbrace {{\tt\char123}} -\def\myrbrace {{\tt\char125}} -\let\{=\mylbrace -\let\}=\myrbrace -\begingroup - % Definitions to produce actual \{ & \} command in an index. - \catcode`\{ = 12 \catcode`\} = 12 - \catcode`\[ = 1 \catcode`\] = 2 - \catcode`\@ = 0 \catcode`\\ = 12 - @gdef@lbracecmd[\{]% - @gdef@rbracecmd[\}]% -@endgroup - -% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent -% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. -\let\, = \c -\let\dotaccent = \. -\def\ringaccent#1{{\accent23 #1}} -\let\tieaccent = \t -\let\ubaraccent = \b -\let\udotaccent = \d - -% Other special characters: @questiondown @exclamdown -% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. -\def\questiondown{?`} -\def\exclamdown{!`} - -% Dotless i and dotless j, used for accents. -\def\imacro{i} -\def\jmacro{j} -\def\dotless#1{% - \def\temp{#1}% - \ifx\temp\imacro \ptexi - \else\ifx\temp\jmacro \j - \else \errmessage{@dotless can be used only with i or j}% - \fi\fi -} - -% Be sure we're in horizontal mode when doing a tie, since we make space -% equivalent to this in @example-like environments. Otherwise, a space -% at the beginning of a line will start with \penalty -- and -% since \penalty is valid in vertical mode, we'd end up putting the -% penalty on the vertical list instead of in the new paragraph. -{\catcode`@ = 11 - % Avoid using \@M directly, because that causes trouble - % if the definition is written into an index file. - \global\let\tiepenalty = \@M - \gdef\tie{\leavevmode\penalty\tiepenalty\ } -} - -% @: forces normal size whitespace following. -\def\:{\spacefactor=1000 } - -% @* forces a line break. -\def\*{\hfil\break\hbox{}\ignorespaces} - -% @. is an end-of-sentence period. -\def\.{.\spacefactor=3000 } - -% @! is an end-of-sentence bang. -\def\!{!\spacefactor=3000 } - -% @? is an end-of-sentence query. -\def\?{?\spacefactor=3000 } - -% @w prevents a word break. Without the \leavevmode, @w at the -% beginning of a paragraph, when TeX is still in vertical mode, would -% produce a whole line of output instead of starting the paragraph. -\def\w#1{\leavevmode\hbox{#1}} - -% @group ... @end group forces ... to be all on one page, by enclosing -% it in a TeX vbox. We use \vtop instead of \vbox to construct the box -% to keep its height that of a normal line. According to the rules for -% \topskip (p.114 of the TeXbook), the glue inserted is -% max (\topskip - \ht (first item), 0). If that height is large, -% therefore, no glue is inserted, and the space between the headline and -% the text is small, which looks bad. -% -\def\group{\begingroup - \ifnum\catcode13=\active \else - \errhelp = \groupinvalidhelp - \errmessage{@group invalid in context where filling is enabled}% - \fi - % - % The \vtop we start below produces a box with normal height and large - % depth; thus, TeX puts \baselineskip glue before it, and (when the - % next line of text is done) \lineskip glue after it. (See p.82 of - % the TeXbook.) Thus, space below is not quite equal to space - % above. But it's pretty close. - \def\Egroup{% - \egroup % End the \vtop. - \endgroup % End the \group. - }% - % - \vtop\bgroup - % We have to put a strut on the last line in case the @group is in - % the midst of an example, rather than completely enclosing it. - % Otherwise, the interline space between the last line of the group - % and the first line afterwards is too small. But we can't put the - % strut in \Egroup, since there it would be on a line by itself. - % Hence this just inserts a strut at the beginning of each line. - \everypar = {\strut}% - % - % Since we have a strut on every line, we don't need any of TeX's - % normal interline spacing. - \offinterlineskip - % - % OK, but now we have to do something about blank - % lines in the input in @example-like environments, which normally - % just turn into \lisppar, which will insert no space now that we've - % turned off the interline space. Simplest is to make them be an - % empty paragraph. - \ifx\par\lisppar - \edef\par{\leavevmode \par}% - % - % Reset ^^M's definition to new definition of \par. - \obeylines - \fi - % - % Do @comment since we are called inside an environment such as - % @example, where each end-of-line in the input causes an - % end-of-line in the output. We don't want the end-of-line after - % the `@group' to put extra space in the output. Since @group - % should appear on a line by itself (according to the Texinfo - % manual), we don't worry about eating any user text. - \comment -} -% -% TeX puts in an \escapechar (i.e., `@') at the beginning of the help -% message, so this ends up printing `@group can only ...'. -% -\newhelp\groupinvalidhelp{% -group can only be used in environments such as @example,^^J% -where each line of input produces a line of output.} - -% @need space-in-mils -% forces a page break if there is not space-in-mils remaining. - -\newdimen\mil \mil=0.001in - -\def\need{\parsearg\needx} - -% Old definition--didn't work. -%\def\needx #1{\par % -%% This method tries to make TeX break the page naturally -%% if the depth of the box does not fit. -%{\baselineskip=0pt% -%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak -%\prevdepth=-1000pt -%}} - -\def\needx#1{% - % Ensure vertical mode, so we don't make a big box in the middle of a - % paragraph. - \par - % - % If the @need value is less than one line space, it's useless. - \dimen0 = #1\mil - \dimen2 = \ht\strutbox - \advance\dimen2 by \dp\strutbox - \ifdim\dimen0 > \dimen2 - % - % Do a \strut just to make the height of this box be normal, so the - % normal leading is inserted relative to the preceding line. - % And a page break here is fine. - \vtop to #1\mil{\strut\vfil}% - % - % TeX does not even consider page breaks if a penalty added to the - % main vertical list is 10000 or more. But in order to see if the - % empty box we just added fits on the page, we must make it consider - % page breaks. On the other hand, we don't want to actually break the - % page after the empty box. So we use a penalty of 9999. - % - % There is an extremely small chance that TeX will actually break the - % page at this \penalty, if there are no other feasible breakpoints in - % sight. (If the user is using lots of big @group commands, which - % almost-but-not-quite fill up a page, TeX will have a hard time doing - % good page breaking, for example.) However, I could not construct an - % example where a page broke at this \penalty; if it happens in a real - % document, then we can reconsider our strategy. - \penalty9999 - % - % Back up by the size of the box, whether we did a page break or not. - \kern -#1\mil - % - % Do not allow a page break right after this kern. - \nobreak - \fi -} - -% @br forces paragraph break - -\let\br = \par - -% @dots{} output an ellipsis using the current font. -% We do .5em per period so that it has the same spacing in a typewriter -% font as three actual period characters. -% -\def\dots{% - \leavevmode - \hbox to 1.5em{% - \hskip 0pt plus 0.25fil minus 0.25fil - .\hss.\hss.% - \hskip 0pt plus 0.5fil minus 0.5fil - }% -} - -% @enddots{} is an end-of-sentence ellipsis. -% -\def\enddots{% - \leavevmode - \hbox to 2em{% - \hskip 0pt plus 0.25fil minus 0.25fil - .\hss.\hss.\hss.% - \hskip 0pt plus 0.5fil minus 0.5fil - }% - \spacefactor=3000 -} - - -% @page forces the start of a new page -% -\def\page{\par\vfill\supereject} - -% @exdent text.... -% outputs text on separate line in roman font, starting at standard page margin - -% This records the amount of indent in the innermost environment. -% That's how much \exdent should take out. -\newskip\exdentamount - -% This defn is used inside fill environments such as @defun. -\def\exdent{\parsearg\exdentyyy} -\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} - -% This defn is used inside nofill environments such as @example. -\def\nofillexdent{\parsearg\nofillexdentyyy} -\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount -\leftline{\hskip\leftskip{\rm#1}}}} - -% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. - -\def\inmargin#1{% -\strut\vadjust{\nobreak\kern-\strutdepth - \vtop to \strutdepth{\baselineskip\strutdepth\vss - \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} -\newskip\inmarginspacing \inmarginspacing=1cm -\def\strutdepth{\dp\strutbox} - -%\hbox{{\rm#1}}\hfil\break}} - -% @include file insert text of that file as input. -% Allow normal characters that we make active in the argument (a file name). -\def\include{\begingroup - \catcode`\\=12 - \catcode`~=12 - \catcode`^=12 - \catcode`_=12 - \catcode`|=12 - \catcode`<=12 - \catcode`>=12 - \catcode`+=12 - \parsearg\includezzz} -% Restore active chars for included file. -\def\includezzz#1{\endgroup\begingroup - % Read the included file in a group so nested @include's work. - \def\thisfile{#1}% - \input\thisfile -\endgroup} - -\def\thisfile{} - -% @center line outputs that line, centered - -\def\center{\parsearg\centerzzz} -\def\centerzzz #1{{\advance\hsize by -\leftskip -\advance\hsize by -\rightskip -\centerline{#1}}} - -% @sp n outputs n lines of vertical space - -\def\sp{\parsearg\spxxx} -\def\spxxx #1{\vskip #1\baselineskip} - -% @comment ...line which is ignored... -% @c is the same as @comment -% @ignore ... @end ignore is another way to write a comment - -\def\comment{\begingroup \catcode`\^^M=\other% -\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% -\commentxxx} -{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} - -\let\c=\comment - -% @paragraphindent NCHARS -% We'll use ems for NCHARS, close enough. -% We cannot implement @paragraphindent asis, though. -% -\def\asisword{asis} % no translation, these are keywords -\def\noneword{none} -% -\def\paragraphindent{\parsearg\doparagraphindent} -\def\doparagraphindent#1{% - \def\temp{#1}% - \ifx\temp\asisword - \else - \ifx\temp\noneword - \defaultparindent = 0pt - \else - \defaultparindent = #1em - \fi - \fi - \parindent = \defaultparindent -} - -% @exampleindent NCHARS -% We'll use ems for NCHARS like @paragraphindent. -% It seems @exampleindent asis isn't necessary, but -% I preserve it to make it similar to @paragraphindent. -\def\exampleindent{\parsearg\doexampleindent} -\def\doexampleindent#1{% - \def\temp{#1}% - \ifx\temp\asisword - \else - \ifx\temp\noneword - \lispnarrowing = 0pt - \else - \lispnarrowing = #1em - \fi - \fi -} - -% @asis just yields its argument. Used with @table, for example. -% -\def\asis#1{#1} - -% @math means output in math mode. -% We don't use $'s directly in the definition of \math because control -% sequences like \math are expanded when the toc file is written. Then, -% we read the toc file back, the $'s will be normal characters (as they -% should be, according to the definition of Texinfo). So we must use a -% control sequence to switch into and out of math mode. -% -% This isn't quite enough for @math to work properly in indices, but it -% seems unlikely it will ever be needed there. -% -\let\implicitmath = $ -\def\math#1{\implicitmath #1\implicitmath} - -% @bullet and @minus need the same treatment as @math, just above. -\def\bullet{\implicitmath\ptexbullet\implicitmath} -\def\minus{\implicitmath-\implicitmath} - -% @refill is a no-op. -\let\refill=\relax - -% If working on a large document in chapters, it is convenient to -% be able to disable indexing, cross-referencing, and contents, for test runs. -% This is done with @novalidate (before @setfilename). -% -\newif\iflinks \linkstrue % by default we want the aux files. -\let\novalidate = \linksfalse - -% @setfilename is done at the beginning of every texinfo file. -% So open here the files we need to have open while reading the input. -% This makes it possible to make a .fmt file for texinfo. -\def\setfilename{% - \iflinks - \readauxfile - \fi % \openindices needs to do some work in any case. - \openindices - \fixbackslash % Turn off hack to swallow `\input texinfo'. - \global\let\setfilename=\comment % Ignore extra @setfilename cmds. - % - % If texinfo.cnf is present on the system, read it. - % Useful for site-wide @afourpaper, etc. - % Just to be on the safe side, close the input stream before the \input. - \openin 1 texinfo.cnf - \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi - \closein1 - \temp - % - \comment % Ignore the actual filename. -} - -% Called from \setfilename. -% -\def\openindices{% - \newindex{cp}% - \newcodeindex{fn}% - \newcodeindex{vr}% - \newcodeindex{tp}% - \newcodeindex{ky}% - \newcodeindex{pg}% -} - -% @bye. -\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} - - -\message{pdf,} -% adobe `portable' document format -\newcount\tempnum -\newcount\lnkcount -\newtoks\filename -\newcount\filenamelength -\newcount\pgn -\newtoks\toksA -\newtoks\toksB -\newtoks\toksC -\newtoks\toksD -\newbox\boxA -\newcount\countA -\newif\ifpdf -\newif\ifpdfmakepagedest - -\ifx\pdfoutput\undefined - \pdffalse - \let\pdfmkdest = \gobble - \let\pdfurl = \gobble - \let\endlink = \relax - \let\linkcolor = \relax - \let\pdfmakeoutlines = \relax -\else - \pdftrue - \pdfoutput = 1 - \input pdfcolor - \def\dopdfimage#1#2#3{% - \def\imagewidth{#2}% - \def\imageheight{#3}% - \ifnum\pdftexversion < 14 - \pdfimage - \else - \pdfximage - \fi - \ifx\empty\imagewidth\else width \imagewidth \fi - \ifx\empty\imageheight\else height \imageheight \fi - {#1.pdf}% - \ifnum\pdftexversion < 14 \else - \pdfrefximage \pdflastximage - \fi} - \def\pdfmkdest#1{\pdfdest name{#1@} xyz} - \def\pdfmkpgn#1{#1@} - \let\linkcolor = \Cyan - \def\endlink{\Black\pdfendlink} - % Adding outlines to PDF; macros for calculating structure of outlines - % come from Petr Olsak - \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% - \else \csname#1\endcsname \fi} - \def\advancenumber#1{\tempnum=\expnumber{#1}\relax - \advance\tempnum by1 - \expandafter\xdef\csname#1\endcsname{\the\tempnum}} - \def\pdfmakeoutlines{{% - \openin 1 \jobname.toc - \ifeof 1\else\bgroup - \closein 1 - \indexnofonts - \def\tt{} - % thanh's hack / proper braces in bookmarks - \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace - \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace - % - \def\chapentry ##1##2##3{} - \def\unnumbchapentry ##1##2{} - \def\secentry ##1##2##3##4{\advancenumber{chap##2}} - \def\unnumbsecentry ##1##2{} - \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} - \def\unnumbsubsecentry ##1##2{} - \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} - \def\unnumbsubsubsecentry ##1##2{} - \input \jobname.toc - \def\chapentry ##1##2##3{% - \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} - \def\unnumbchapentry ##1##2{% - \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} - \def\secentry ##1##2##3##4{% - \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} - \def\unnumbsecentry ##1##2{% - \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} - \def\subsecentry ##1##2##3##4##5{% - \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} - \def\unnumbsubsecentry ##1##2{% - \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} - \def\subsubsecentry ##1##2##3##4##5##6{% - \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} - \def\unnumbsubsubsecentry ##1##2{% - \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} - \input \jobname.toc - \egroup\fi - }} - \def\makelinks #1,{% - \def\params{#1}\def\E{END}% - \ifx\params\E - \let\nextmakelinks=\relax - \else - \let\nextmakelinks=\makelinks - \ifnum\lnkcount>0,\fi - \picknum{#1}% - \startlink attr{/Border [0 0 0]} - goto name{\pdfmkpgn{\the\pgn}}% - \linkcolor #1% - \advance\lnkcount by 1% - \endlink - \fi - \nextmakelinks - } - \def\picknum#1{\expandafter\pn#1} - \def\pn#1{% - \def\p{#1}% - \ifx\p\lbrace - \let\nextpn=\ppn - \else - \let\nextpn=\ppnn - \def\first{#1} - \fi - \nextpn - } - \def\ppn#1{\pgn=#1\gobble} - \def\ppnn{\pgn=\first} - \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} - \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} - \def\skipspaces#1{\def\PP{#1}\def\D{|}% - \ifx\PP\D\let\nextsp\relax - \else\let\nextsp\skipspaces - \ifx\p\space\else\addtokens{\filename}{\PP}% - \advance\filenamelength by 1 - \fi - \fi - \nextsp} - \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} - \ifnum\pdftexversion < 14 - \let \startlink \pdfannotlink - \else - \let \startlink \pdfstartlink - \fi - \def\pdfurl#1{% - \begingroup - \normalturnoffactive\def\@{@}% - \leavevmode\Red - \startlink attr{/Border [0 0 0]}% - user{/Subtype /Link /A << /S /URI /URI (#1) >>}% - % #1 - \endgroup} - \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} - \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} - \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} - \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} - \def\maketoks{% - \expandafter\poptoks\the\toksA|ENDTOKS| - \ifx\first0\adn0 - \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 - \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 - \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 - \else - \ifnum0=\countA\else\makelink\fi - \ifx\first.\let\next=\done\else - \let\next=\maketoks - \addtokens{\toksB}{\the\toksD} - \ifx\first,\addtokens{\toksB}{\space}\fi - \fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \next} - \def\makelink{\addtokens{\toksB}% - {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} - \def\pdflink#1{% - \startlink attr{/Border [0 0 0]} goto name{\mkpgn{#1}} - \linkcolor #1\endlink} - \def\mkpgn#1{#1@} - \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} -\fi % \ifx\pdfoutput - - -\message{fonts,} -% Font-change commands. - -% Texinfo sort of supports the sans serif font style, which plain TeX does not. -% So we set up a \sf analogous to plain's \rm, etc. -\newfam\sffam -\def\sf{\fam=\sffam \tensf} -\let\li = \sf % Sometimes we call it \li, not \sf. - -% We don't need math for this one. -\def\ttsl{\tenttsl} - -% Use Computer Modern fonts at \magstephalf (11pt). -\newcount\mainmagstep -\mainmagstep=\magstephalf - -% Set the font macro #1 to the font named #2, adding on the -% specified font prefix (normally `cm'). -% #3 is the font's design size, #4 is a scale factor -\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} - -% Use cm as the default font prefix. -% To specify the font prefix, you must define \fontprefix -% before you read in texinfo.tex. -\ifx\fontprefix\undefined -\def\fontprefix{cm} -\fi -% Support font families that don't use the same naming scheme as CM. -\def\rmshape{r} -\def\rmbshape{bx} %where the normal face is bold -\def\bfshape{b} -\def\bxshape{bx} -\def\ttshape{tt} -\def\ttbshape{tt} -\def\ttslshape{sltt} -\def\itshape{ti} -\def\itbshape{bxti} -\def\slshape{sl} -\def\slbshape{bxsl} -\def\sfshape{ss} -\def\sfbshape{ss} -\def\scshape{csc} -\def\scbshape{csc} - -\ifx\bigger\relax -\let\mainmagstep=\magstep1 -\setfont\textrm\rmshape{12}{1000} -\setfont\texttt\ttshape{12}{1000} -\else -\setfont\textrm\rmshape{10}{\mainmagstep} -\setfont\texttt\ttshape{10}{\mainmagstep} -\fi -% Instead of cmb10, you many want to use cmbx10. -% cmbx10 is a prettier font on its own, but cmb10 -% looks better when embedded in a line with cmr10. -\setfont\textbf\bfshape{10}{\mainmagstep} -\setfont\textit\itshape{10}{\mainmagstep} -\setfont\textsl\slshape{10}{\mainmagstep} -\setfont\textsf\sfshape{10}{\mainmagstep} -\setfont\textsc\scshape{10}{\mainmagstep} -\setfont\textttsl\ttslshape{10}{\mainmagstep} -\font\texti=cmmi10 scaled \mainmagstep -\font\textsy=cmsy10 scaled \mainmagstep - -% A few fonts for @defun, etc. -\setfont\defbf\bxshape{10}{\magstep1} %was 1314 -\setfont\deftt\ttshape{10}{\magstep1} -\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} - -% Fonts for indices, footnotes, small examples (9pt). -\setfont\smallrm\rmshape{9}{1000} -\setfont\smalltt\ttshape{9}{1000} -\setfont\smallbf\bfshape{10}{900} -\setfont\smallit\itshape{9}{1000} -\setfont\smallsl\slshape{9}{1000} -\setfont\smallsf\sfshape{9}{1000} -\setfont\smallsc\scshape{10}{900} -\setfont\smallttsl\ttslshape{10}{900} -\font\smalli=cmmi9 -\font\smallsy=cmsy9 - -% Fonts for title page: -\setfont\titlerm\rmbshape{12}{\magstep3} -\setfont\titleit\itbshape{10}{\magstep4} -\setfont\titlesl\slbshape{10}{\magstep4} -\setfont\titlett\ttbshape{12}{\magstep3} -\setfont\titlettsl\ttslshape{10}{\magstep4} -\setfont\titlesf\sfbshape{17}{\magstep1} -\let\titlebf=\titlerm -\setfont\titlesc\scbshape{10}{\magstep4} -\font\titlei=cmmi12 scaled \magstep3 -\font\titlesy=cmsy10 scaled \magstep4 -\def\authorrm{\secrm} - -% Chapter (and unnumbered) fonts (17.28pt). -\setfont\chaprm\rmbshape{12}{\magstep2} -\setfont\chapit\itbshape{10}{\magstep3} -\setfont\chapsl\slbshape{10}{\magstep3} -\setfont\chaptt\ttbshape{12}{\magstep2} -\setfont\chapttsl\ttslshape{10}{\magstep3} -\setfont\chapsf\sfbshape{17}{1000} -\let\chapbf=\chaprm -\setfont\chapsc\scbshape{10}{\magstep3} -\font\chapi=cmmi12 scaled \magstep2 -\font\chapsy=cmsy10 scaled \magstep3 - -% Section fonts (14.4pt). -\setfont\secrm\rmbshape{12}{\magstep1} -\setfont\secit\itbshape{10}{\magstep2} -\setfont\secsl\slbshape{10}{\magstep2} -\setfont\sectt\ttbshape{12}{\magstep1} -\setfont\secttsl\ttslshape{10}{\magstep2} -\setfont\secsf\sfbshape{12}{\magstep1} -\let\secbf\secrm -\setfont\secsc\scbshape{10}{\magstep2} -\font\seci=cmmi12 scaled \magstep1 -\font\secsy=cmsy10 scaled \magstep2 - -% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. -% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. -% \setfont\ssecsl\slshape{10}{\magstep1} -% \setfont\ssectt\ttshape{10}{\magstep1} -% \setfont\ssecsf\sfshape{10}{\magstep1} - -%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. -%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than -%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. -%\setfont\ssectt\ttshape{10}{1315} -%\setfont\ssecsf\sfshape{10}{1315} - -%\let\ssecbf=\ssecrm - -% Subsection fonts (13.15pt). -\setfont\ssecrm\rmbshape{12}{\magstephalf} -\setfont\ssecit\itbshape{10}{1315} -\setfont\ssecsl\slbshape{10}{1315} -\setfont\ssectt\ttbshape{12}{\magstephalf} -\setfont\ssecttsl\ttslshape{10}{1315} -\setfont\ssecsf\sfbshape{12}{\magstephalf} -\let\ssecbf\ssecrm -\setfont\ssecsc\scbshape{10}{\magstep1} -\font\sseci=cmmi12 scaled \magstephalf -\font\ssecsy=cmsy10 scaled 1315 -% The smallcaps and symbol fonts should actually be scaled \magstep1.5, -% but that is not a standard magnification. - -% In order for the font changes to affect most math symbols and letters, -% we have to define the \textfont of the standard families. Since -% texinfo doesn't allow for producing subscripts and superscripts, we -% don't bother to reset \scriptfont and \scriptscriptfont (which would -% also require loading a lot more fonts). -% -\def\resetmathfonts{% - \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy - \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf - \textfont\ttfam = \tentt \textfont\sffam = \tensf -} - - -% The font-changing commands redefine the meanings of \tenSTYLE, instead -% of just \STYLE. We do this so that font changes will continue to work -% in math mode, where it is the current \fam that is relevant in most -% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam -% \tenbf}, for example. By redefining \tenbf, we obviate the need to -% redefine \bf itself. -\def\textfonts{% - \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl - \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc - \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl - \resetmathfonts} -\def\titlefonts{% - \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl - \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc - \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy - \let\tenttsl=\titlettsl - \resetmathfonts \setleading{25pt}} -\def\titlefont#1{{\titlefonts\rm #1}} -\def\chapfonts{% - \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl - \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc - \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl - \resetmathfonts \setleading{19pt}} -\def\secfonts{% - \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl - \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc - \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl - \resetmathfonts \setleading{16pt}} -\def\subsecfonts{% - \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl - \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc - \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl - \resetmathfonts \setleading{15pt}} -\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? -\def\smallfonts{% - \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl - \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc - \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy - \let\tenttsl=\smallttsl - \resetmathfonts \setleading{11pt}} - -% Set up the default fonts, so we can use them for creating boxes. -% -\textfonts - -% Define these so they can be easily changed for other fonts. -\def\angleleft{$\langle$} -\def\angleright{$\rangle$} - -% Count depth in font-changes, for error checks -\newcount\fontdepth \fontdepth=0 - -% Fonts for short table of contents. -\setfont\shortcontrm\rmshape{12}{1000} -\setfont\shortcontbf\bxshape{12}{1000} -\setfont\shortcontsl\slshape{12}{1000} - -%% Add scribe-like font environments, plus @l for inline lisp (usually sans -%% serif) and @ii for TeX italic - -% \smartitalic{ARG} outputs arg in italics, followed by an italic correction -% unless the following character is such as not to need one. -\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} -\def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx} -\def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx} - -\let\i=\smartitalic -\let\var=\smartslanted -\let\dfn=\smartslanted -\let\emph=\smartitalic -\let\cite=\smartslanted - -\def\b#1{{\bf #1}} -\let\strong=\b - -% We can't just use \exhyphenpenalty, because that only has effect at -% the end of a paragraph. Restore normal hyphenation at the end of the -% group within which \nohyphenation is presumably called. -% -\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} -\def\restorehyphenation{\hyphenchar\font = `- } - -\def\t#1{% - {\tt \rawbackslash \frenchspacing #1}% - \null -} -\let\ttfont=\t -\def\samp#1{`\tclose{#1}'\null} -\setfont\keyrm\rmshape{8}{1000} -\font\keysy=cmsy9 -\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% - \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% - \vbox{\hrule\kern-0.4pt - \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% - \kern-0.4pt\hrule}% - \kern-.06em\raise0.4pt\hbox{\angleright}}}} -% The old definition, with no lozenge: -%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} -\def\ctrl #1{{\tt \rawbackslash \hat}#1} - -% @file, @option are the same as @samp. -\let\file=\samp -\let\option=\samp - -% @code is a modification of @t, -% which makes spaces the same size as normal in the surrounding text. -\def\tclose#1{% - {% - % Change normal interword space to be same as for the current font. - \spaceskip = \fontdimen2\font - % - % Switch to typewriter. - \tt - % - % But `\ ' produces the large typewriter interword space. - \def\ {{\spaceskip = 0pt{} }}% - % - % Turn off hyphenation. - \nohyphenation - % - \rawbackslash - \frenchspacing - #1% - }% - \null -} - -% We *must* turn on hyphenation at `-' and `_' in \code. -% Otherwise, it is too hard to avoid overfull hboxes -% in the Emacs manual, the Library manual, etc. - -% Unfortunately, TeX uses one parameter (\hyphenchar) to control -% both hyphenation at - and hyphenation within words. -% We must therefore turn them both off (\tclose does that) -% and arrange explicitly to hyphenate at a dash. -% -- rms. -{ - \catcode`\-=\active - \catcode`\_=\active - % - \global\def\code{\begingroup - \catcode`\-=\active \let-\codedash - \catcode`\_=\active \let_\codeunder - \codex - } - % - % If we end up with any active - characters when handling the index, - % just treat them as a normal -. - \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} -} - -\def\realdash{-} -\def\codedash{-\discretionary{}{}{}} -\def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} -\def\codex #1{\tclose{#1}\endgroup} - -%\let\exp=\tclose %Was temporary - -% @kbd is like @code, except that if the argument is just one @key command, -% then @kbd has no effect. - -% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), -% `example' (@kbd uses ttsl only inside of @example and friends), -% or `code' (@kbd uses normal tty font always). -\def\kbdinputstyle{\parsearg\kbdinputstylexxx} -\def\kbdinputstylexxx#1{% - \def\arg{#1}% - \ifx\arg\worddistinct - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% - \else\ifx\arg\wordexample - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% - \else\ifx\arg\wordcode - \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% - \fi\fi\fi -} -\def\worddistinct{distinct} -\def\wordexample{example} -\def\wordcode{code} - -% Default is kbdinputdistinct. (Too much of a hassle to call the macro, -% the catcodes are wrong for parsearg to work.) -\gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} - -\def\xkey{\key} -\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% -\ifx\one\xkey\ifx\threex\three \key{#2}% -\else{\tclose{\kbdfont\look}}\fi -\else{\tclose{\kbdfont\look}}\fi} - -% For @url, @env, @command quotes seem unnecessary, so use \code. -\let\url=\code -\let\env=\code -\let\command=\code - -% @uref (abbreviation for `urlref') takes an optional (comma-separated) -% second argument specifying the text to display and an optional third -% arg as text to display instead of (rather than in addition to) the url -% itself. First (mandatory) arg is the url. Perhaps eventually put in -% a hypertex \special here. -% -\def\uref#1{\douref #1,,,\finish} -\def\douref#1,#2,#3,#4\finish{\begingroup - \unsepspaces - \pdfurl{#1}% - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt - \unhbox0 % third arg given, show only that - \else - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \ifpdf - \unhbox0 % PDF: 2nd arg given, show only it - \else - \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url - \fi - \else - \code{#1}% only url given, so show it - \fi - \fi - \endlink -\endgroup} - -% rms does not like angle brackets --karl, 17may97. -% So now @email is just like @uref, unless we are pdf. -% -%\def\email#1{\angleleft{\tt #1}\angleright} -\ifpdf - \def\email#1{\doemail#1,,\finish} - \def\doemail#1,#2,#3\finish{\begingroup - \unsepspaces - \pdfurl{mailto:#1}% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi - \endlink - \endgroup} -\else - \let\email=\uref -\fi - -% Check if we are currently using a typewriter font. Since all the -% Computer Modern typewriter fonts have zero interword stretch (and -% shrink), and it is reasonable to expect all typewriter fonts to have -% this property, we can check that font parameter. -% -\def\ifmonospace{\ifdim\fontdimen3\font=0pt } - -% Typeset a dimension, e.g., `in' or `pt'. The only reason for the -% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. -% -\def\dmn#1{\thinspace #1} - -\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} - -% @l was never documented to mean ``switch to the Lisp font'', -% and it is not used as such in any manual I can find. We need it for -% Polish suppressed-l. --karl, 22sep96. -%\def\l#1{{\li #1}\null} - -% Explicit font changes: @r, @sc, undocumented @ii. -\def\r#1{{\rm #1}} % roman font -\def\sc#1{{\smallcaps#1}} % smallcaps font -\def\ii#1{{\it #1}} % italic font - -% @acronym downcases the argument and prints in smallcaps. -\def\acronym#1{{\smallcaps \lowercase{#1}}} - -% @pounds{} is a sterling sign. -\def\pounds{{\it\$}} - - -\message{page headings,} - -\newskip\titlepagetopglue \titlepagetopglue = 1.5in -\newskip\titlepagebottomglue \titlepagebottomglue = 2pc - -% First the title page. Must do @settitle before @titlepage. -\newif\ifseenauthor -\newif\iffinishedtitlepage - -% Do an implicit @contents or @shortcontents after @end titlepage if the -% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. -% -\newif\ifsetcontentsaftertitlepage - \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue -\newif\ifsetshortcontentsaftertitlepage - \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue - -\def\shorttitlepage{\parsearg\shorttitlepagezzz} -\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% - \endgroup\page\hbox{}\page} - -\def\titlepage{\begingroup \parindent=0pt \textfonts - \let\subtitlerm=\tenrm - \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% - % - \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% - % - % Leave some space at the very top of the page. - \vglue\titlepagetopglue - % - % Now you can print the title using @title. - \def\title{\parsearg\titlezzz}% - \def\titlezzz##1{\leftline{\titlefonts\rm ##1} - % print a rule at the page bottom also. - \finishedtitlepagefalse - \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% - % No rule at page bottom unless we print one at the top with @title. - \finishedtitlepagetrue - % - % Now you can put text using @subtitle. - \def\subtitle{\parsearg\subtitlezzz}% - \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% - % - % @author should come last, but may come many times. - \def\author{\parsearg\authorzzz}% - \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi - {\authorfont \leftline{##1}}}% - % - % Most title ``pages'' are actually two pages long, with space - % at the top of the second. We don't want the ragged left on the second. - \let\oldpage = \page - \def\page{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - \oldpage - \let\page = \oldpage - \hbox{}}% -% \def\page{\oldpage \hbox{}} -} - -\def\Etitlepage{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - % It is important to do the page break before ending the group, - % because the headline and footline are only empty inside the group. - % If we use the new definition of \page, we always get a blank page - % after the title page, which we certainly don't want. - \oldpage - \endgroup - % - % If they want short, they certainly want long too. - \ifsetshortcontentsaftertitlepage - \shortcontents - \contents - \global\let\shortcontents = \relax - \global\let\contents = \relax - \fi - % - \ifsetcontentsaftertitlepage - \contents - \global\let\contents = \relax - \global\let\shortcontents = \relax - \fi - % - \ifpdf \pdfmakepagedesttrue \fi - % - \HEADINGSon -} - -\def\finishtitlepage{% - \vskip4pt \hrule height 2pt width \hsize - \vskip\titlepagebottomglue - \finishedtitlepagetrue -} - -%%% Set up page headings and footings. - -\let\thispage=\folio - -\newtoks\evenheadline % headline on even pages -\newtoks\oddheadline % headline on odd pages -\newtoks\evenfootline % footline on even pages -\newtoks\oddfootline % footline on odd pages - -% Now make Tex use those variables -\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline - \else \the\evenheadline \fi}} -\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline - \else \the\evenfootline \fi}\HEADINGShook} -\let\HEADINGShook=\relax - -% Commands to set those variables. -% For example, this is what @headings on does -% @evenheading @thistitle|@thispage|@thischapter -% @oddheading @thischapter|@thispage|@thistitle -% @evenfooting @thisfile|| -% @oddfooting ||@thisfile - -\def\evenheading{\parsearg\evenheadingxxx} -\def\oddheading{\parsearg\oddheadingxxx} -\def\everyheading{\parsearg\everyheadingxxx} - -\def\evenfooting{\parsearg\evenfootingxxx} -\def\oddfooting{\parsearg\oddfootingxxx} -\def\everyfooting{\parsearg\everyfootingxxx} - -{\catcode`\@=0 % - -\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} -\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% -\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} -\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% -\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% - -\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} -\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% -\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} -\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% - \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% - % - % Leave some space for the footline. Hopefully ok to assume - % @evenfooting will not be used by itself. - \global\advance\pageheight by -\baselineskip - \global\advance\vsize by -\baselineskip -} - -\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} -% -}% unbind the catcode of @. - -% @headings double turns headings on for double-sided printing. -% @headings single turns headings on for single-sided printing. -% @headings off turns them off. -% @headings on same as @headings double, retained for compatibility. -% @headings after turns on double-sided headings after this page. -% @headings doubleafter turns on double-sided headings after this page. -% @headings singleafter turns on single-sided headings after this page. -% By default, they are off at the start of a document, -% and turned `on' after @end titlepage. - -\def\headings #1 {\csname HEADINGS#1\endcsname} - -\def\HEADINGSoff{ -\global\evenheadline={\hfil} \global\evenfootline={\hfil} -\global\oddheadline={\hfil} \global\oddfootline={\hfil}} -\HEADINGSoff -% When we turn headings on, set the page number to 1. -% For double-sided printing, put current file name in lower left corner, -% chapter name on inside top of right hand pages, document -% title on inside top of left hand pages, and page numbers on outside top -% edge of all pages. -\def\HEADINGSdouble{ -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage -} -\let\contentsalignmacro = \chappager - -% For single-sided printing, chapter title goes across top left of page, -% page number on top right. -\def\HEADINGSsingle{ -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chappager -} -\def\HEADINGSon{\HEADINGSdouble} - -\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} -\let\HEADINGSdoubleafter=\HEADINGSafter -\def\HEADINGSdoublex{% -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage -} - -\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} -\def\HEADINGSsinglex{% -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chappager -} - -% Subroutines used in generating headings -% Produces Day Month Year style of output. -\def\today{% - \number\day\space - \ifcase\month - \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr - \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug - \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec - \fi - \space\number\year} - -% @settitle line... specifies the title of the document, for headings. -% It generates no output of its own. -\def\thistitle{\putwordNoTitle} -\def\settitle{\parsearg\settitlezzz} -\def\settitlezzz #1{\gdef\thistitle{#1}} - - -\message{tables,} -% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). - -% default indentation of table text -\newdimen\tableindent \tableindent=.8in -% default indentation of @itemize and @enumerate text -\newdimen\itemindent \itemindent=.3in -% margin between end of table item and start of table text. -\newdimen\itemmargin \itemmargin=.1in - -% used internally for \itemindent minus \itemmargin -\newdimen\itemmax - -% Note @table, @vtable, and @vtable define @item, @itemx, etc., with -% these defs. -% They also define \itemindex -% to index the item name in whatever manner is desired (perhaps none). - -\newif\ifitemxneedsnegativevskip - -\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} - -\def\internalBitem{\smallbreak \parsearg\itemzzz} -\def\internalBitemx{\itemxpar \parsearg\itemzzz} - -\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} -\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} - -\def\internalBkitem{\smallbreak \parsearg\kitemzzz} -\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} - -\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% - \itemzzz {#1}} - -\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% - \itemzzz {#1}} - -\def\itemzzz #1{\begingroup % - \advance\hsize by -\rightskip - \advance\hsize by -\tableindent - \setbox0=\hbox{\itemfont{#1}}% - \itemindex{#1}% - \nobreak % This prevents a break before @itemx. - % - % If the item text does not fit in the space we have, put it on a line - % by itself, and do not allow a page break either before or after that - % line. We do not start a paragraph here because then if the next - % command is, e.g., @kindex, the whatsit would get put into the - % horizontal list on a line by itself, resulting in extra blank space. - \ifdim \wd0>\itemmax - % - % Make this a paragraph so we get the \parskip glue and wrapping, - % but leave it ragged-right. - \begingroup - \advance\leftskip by-\tableindent - \advance\hsize by\tableindent - \advance\rightskip by0pt plus1fil - \leavevmode\unhbox0\par - \endgroup - % - % We're going to be starting a paragraph, but we don't want the - % \parskip glue -- logically it's part of the @item we just started. - \nobreak \vskip-\parskip - % - % Stop a page break at the \parskip glue coming up. Unfortunately - % we can't prevent a possible page break at the following - % \baselineskip glue. - \nobreak - \endgroup - \itemxneedsnegativevskipfalse - \else - % The item text fits into the space. Start a paragraph, so that the - % following text (if any) will end up on the same line. - \noindent - % Do this with kerns and \unhbox so that if there is a footnote in - % the item text, it can migrate to the main vertical list and - % eventually be printed. - \nobreak\kern-\tableindent - \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 - \unhbox0 - \nobreak\kern\dimen0 - \endgroup - \itemxneedsnegativevskiptrue - \fi -} - -\def\item{\errmessage{@item while not in a table}} -\def\itemx{\errmessage{@itemx while not in a table}} -\def\kitem{\errmessage{@kitem while not in a table}} -\def\kitemx{\errmessage{@kitemx while not in a table}} -\def\xitem{\errmessage{@xitem while not in a table}} -\def\xitemx{\errmessage{@xitemx while not in a table}} - -% Contains a kludge to get @end[description] to work. -\def\description{\tablez{\dontindex}{1}{}{}{}{}} - -% @table, @ftable, @vtable. -\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} -{\obeylines\obeyspaces% -\gdef\tablex #1^^M{% -\tabley\dontindex#1 \endtabley}} - -\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} -{\obeylines\obeyspaces% -\gdef\ftablex #1^^M{% -\tabley\fnitemindex#1 \endtabley -\def\Eftable{\endgraf\afterenvbreak\endgroup}% -\let\Etable=\relax}} - -\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} -{\obeylines\obeyspaces% -\gdef\vtablex #1^^M{% -\tabley\vritemindex#1 \endtabley -\def\Evtable{\endgraf\afterenvbreak\endgroup}% -\let\Etable=\relax}} - -\def\dontindex #1{} -\def\fnitemindex #1{\doind {fn}{\code{#1}}}% -\def\vritemindex #1{\doind {vr}{\code{#1}}}% - -{\obeyspaces % -\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% -\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} - -\def\tablez #1#2#3#4#5#6{% -\aboveenvbreak % -\begingroup % -\def\Edescription{\Etable}% Necessary kludge. -\let\itemindex=#1% -\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % -\ifnum 0#4>0 \tableindent=#4\mil \fi % -\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % -\def\itemfont{#2}% -\itemmax=\tableindent % -\advance \itemmax by -\itemmargin % -\advance \leftskip by \tableindent % -\exdentamount=\tableindent -\parindent = 0pt -\parskip = \smallskipamount -\ifdim \parskip=0pt \parskip=2pt \fi% -\def\Etable{\endgraf\afterenvbreak\endgroup}% -\let\item = \internalBitem % -\let\itemx = \internalBitemx % -\let\kitem = \internalBkitem % -\let\kitemx = \internalBkitemx % -\let\xitem = \internalBxitem % -\let\xitemx = \internalBxitemx % -} - -% This is the counter used by @enumerate, which is really @itemize - -\newcount \itemno - -\def\itemize{\parsearg\itemizezzz} - -\def\itemizezzz #1{% - \begingroup % ended by the @end itemize - \itemizey {#1}{\Eitemize} -} - -\def\itemizey #1#2{% -\aboveenvbreak % -\itemmax=\itemindent % -\advance \itemmax by -\itemmargin % -\advance \leftskip by \itemindent % -\exdentamount=\itemindent -\parindent = 0pt % -\parskip = \smallskipamount % -\ifdim \parskip=0pt \parskip=2pt \fi% -\def#2{\endgraf\afterenvbreak\endgroup}% -\def\itemcontents{#1}% -\let\item=\itemizeitem} - -% Set sfcode to normal for the chars that usually have another value. -% These are `.?!:;,' -\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 - \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } - -% \splitoff TOKENS\endmark defines \first to be the first token in -% TOKENS, and \rest to be the remainder. -% -\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% - -% Allow an optional argument of an uppercase letter, lowercase letter, -% or number, to specify the first label in the enumerated list. No -% argument is the same as `1'. -% -\def\enumerate{\parsearg\enumeratezzz} -\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} -\def\enumeratey #1 #2\endenumeratey{% - \begingroup % ended by the @end enumerate - % - % If we were given no argument, pretend we were given `1'. - \def\thearg{#1}% - \ifx\thearg\empty \def\thearg{1}\fi - % - % Detect if the argument is a single token. If so, it might be a - % letter. Otherwise, the only valid thing it can be is a number. - % (We will always have one token, because of the test we just made. - % This is a good thing, since \splitoff doesn't work given nothing at - % all -- the first parameter is undelimited.) - \expandafter\splitoff\thearg\endmark - \ifx\rest\empty - % Only one token in the argument. It could still be anything. - % A ``lowercase letter'' is one whose \lccode is nonzero. - % An ``uppercase letter'' is one whose \lccode is both nonzero, and - % not equal to itself. - % Otherwise, we assume it's a number. - % - % We need the \relax at the end of the \ifnum lines to stop TeX from - % continuing to look for a . - % - \ifnum\lccode\expandafter`\thearg=0\relax - \numericenumerate % a number (we hope) - \else - % It's a letter. - \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax - \lowercaseenumerate % lowercase letter - \else - \uppercaseenumerate % uppercase letter - \fi - \fi - \else - % Multiple tokens in the argument. We hope it's a number. - \numericenumerate - \fi -} - -% An @enumerate whose labels are integers. The starting integer is -% given in \thearg. -% -\def\numericenumerate{% - \itemno = \thearg - \startenumeration{\the\itemno}% -} - -% The starting (lowercase) letter is in \thearg. -\def\lowercaseenumerate{% - \itemno = \expandafter`\thearg - \startenumeration{% - % Be sure we're not beyond the end of the alphabet. - \ifnum\itemno=0 - \errmessage{No more lowercase letters in @enumerate; get a bigger - alphabet}% - \fi - \char\lccode\itemno - }% -} - -% The starting (uppercase) letter is in \thearg. -\def\uppercaseenumerate{% - \itemno = \expandafter`\thearg - \startenumeration{% - % Be sure we're not beyond the end of the alphabet. - \ifnum\itemno=0 - \errmessage{No more uppercase letters in @enumerate; get a bigger - alphabet} - \fi - \char\uccode\itemno - }% -} - -% Call itemizey, adding a period to the first argument and supplying the -% common last two arguments. Also subtract one from the initial value in -% \itemno, since @item increments \itemno. -% -\def\startenumeration#1{% - \advance\itemno by -1 - \itemizey{#1.}\Eenumerate\flushcr -} - -% @alphaenumerate and @capsenumerate are abbreviations for giving an arg -% to @enumerate. -% -\def\alphaenumerate{\enumerate{a}} -\def\capsenumerate{\enumerate{A}} -\def\Ealphaenumerate{\Eenumerate} -\def\Ecapsenumerate{\Eenumerate} - -% Definition of @item while inside @itemize. - -\def\itemizeitem{% -\advance\itemno by 1 -{\let\par=\endgraf \smallbreak}% -\ifhmode \errmessage{In hmode at itemizeitem}\fi -{\parskip=0in \hskip 0pt -\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% -\vadjust{\penalty 1200}}% -\flushcr} - -% @multitable macros -% Amy Hendrickson, 8/18/94, 3/6/96 -% -% @multitable ... @end multitable will make as many columns as desired. -% Contents of each column will wrap at width given in preamble. Width -% can be specified either with sample text given in a template line, -% or in percent of \hsize, the current width of text on page. - -% Table can continue over pages but will only break between lines. - -% To make preamble: -% -% Either define widths of columns in terms of percent of \hsize: -% @multitable @columnfractions .25 .3 .45 -% @item ... -% -% Numbers following @columnfractions are the percent of the total -% current hsize to be used for each column. You may use as many -% columns as desired. - - -% Or use a template: -% @multitable {Column 1 template} {Column 2 template} {Column 3 template} -% @item ... -% using the widest term desired in each column. -% -% For those who want to use more than one line's worth of words in -% the preamble, break the line within one argument and it -% will parse correctly, i.e., -% -% @multitable {Column 1 template} {Column 2 template} {Column 3 -% template} -% Not: -% @multitable {Column 1 template} {Column 2 template} -% {Column 3 template} - -% Each new table line starts with @item, each subsequent new column -% starts with @tab. Empty columns may be produced by supplying @tab's -% with nothing between them for as many times as empty columns are needed, -% ie, @tab@tab@tab will produce two empty columns. - -% @item, @tab, @multitable or @end multitable do not need to be on their -% own lines, but it will not hurt if they are. - -% Sample multitable: - -% @multitable {Column 1 template} {Column 2 template} {Column 3 template} -% @item first col stuff @tab second col stuff @tab third col -% @item -% first col stuff -% @tab -% second col stuff -% @tab -% third col -% @item first col stuff @tab second col stuff -% @tab Many paragraphs of text may be used in any column. -% -% They will wrap at the width determined by the template. -% @item@tab@tab This will be in third column. -% @end multitable - -% Default dimensions may be reset by user. -% @multitableparskip is vertical space between paragraphs in table. -% @multitableparindent is paragraph indent in table. -% @multitablecolmargin is horizontal space to be left between columns. -% @multitablelinespace is space to leave between table items, baseline -% to baseline. -% 0pt means it depends on current normal line spacing. -% -\newskip\multitableparskip -\newskip\multitableparindent -\newdimen\multitablecolspace -\newskip\multitablelinespace -\multitableparskip=0pt -\multitableparindent=6pt -\multitablecolspace=12pt -\multitablelinespace=0pt - -% Macros used to set up halign preamble: -% -\let\endsetuptable\relax -\def\xendsetuptable{\endsetuptable} -\let\columnfractions\relax -\def\xcolumnfractions{\columnfractions} -\newif\ifsetpercent - -% #1 is the part of the @columnfraction before the decimal point, which -% is presumably either 0 or the empty string (but we don't check, we -% just throw it away). #2 is the decimal part, which we use as the -% percent of \hsize for this column. -\def\pickupwholefraction#1.#2 {% - \global\advance\colcount by 1 - \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% - \setuptable -} - -\newcount\colcount -\def\setuptable#1{% - \def\firstarg{#1}% - \ifx\firstarg\xendsetuptable - \let\go = \relax - \else - \ifx\firstarg\xcolumnfractions - \global\setpercenttrue - \else - \ifsetpercent - \let\go\pickupwholefraction - \else - \global\advance\colcount by 1 - \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator; - % typically that is always in the input, anyway. - \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% - \fi - \fi - \ifx\go\pickupwholefraction - % Put the argument back for the \pickupwholefraction call, so - % we'll always have a period there to be parsed. - \def\go{\pickupwholefraction#1}% - \else - \let\go = \setuptable - \fi% - \fi - \go -} - -% This used to have \hskip1sp. But then the space in a template line is -% not enough. That is bad. So let's go back to just & until we -% encounter the problem it was intended to solve again. -% --karl, nathan@acm.org, 20apr99. -\def\tab{&} - -% @multitable ... @end multitable definitions: -% -\def\multitable{\parsearg\dotable} -\def\dotable#1{\bgroup - \vskip\parskip - \let\item\crcr - \tolerance=9500 - \hbadness=9500 - \setmultitablespacing - \parskip=\multitableparskip - \parindent=\multitableparindent - \overfullrule=0pt - \global\colcount=0 - \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% - % - % To parse everything between @multitable and @item: - \setuptable#1 \endsetuptable - % - % \everycr will reset column counter, \colcount, at the end of - % each line. Every column entry will cause \colcount to advance by one. - % The table preamble - % looks at the current \colcount to find the correct column width. - \everycr{\noalign{% - % - % \filbreak%% keeps underfull box messages off when table breaks over pages. - % Maybe so, but it also creates really weird page breaks when the table - % breaks over pages. Wouldn't \vfil be better? Wait until the problem - % manifests itself, so it can be fixed for real --karl. - \global\colcount=0\relax}}% - % - % This preamble sets up a generic column definition, which will - % be used as many times as user calls for columns. - % \vtop will set a single line and will also let text wrap and - % continue for many paragraphs if desired. - \halign\bgroup&\global\advance\colcount by 1\relax - \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname - % - % In order to keep entries from bumping into each other - % we will add a \leftskip of \multitablecolspace to all columns after - % the first one. - % - % If a template has been used, we will add \multitablecolspace - % to the width of each template entry. - % - % If the user has set preamble in terms of percent of \hsize we will - % use that dimension as the width of the column, and the \leftskip - % will keep entries from bumping into each other. Table will start at - % left margin and final column will justify at right margin. - % - % Make sure we don't inherit \rightskip from the outer environment. - \rightskip=0pt - \ifnum\colcount=1 - % The first column will be indented with the surrounding text. - \advance\hsize by\leftskip - \else - \ifsetpercent \else - % If user has not set preamble in terms of percent of \hsize - % we will advance \hsize by \multitablecolspace. - \advance\hsize by \multitablecolspace - \fi - % In either case we will make \leftskip=\multitablecolspace: - \leftskip=\multitablecolspace - \fi - % Ignoring space at the beginning and end avoids an occasional spurious - % blank line, when TeX decides to break the line at the space before the - % box from the multistrut, so the strut ends up on a line by itself. - % For example: - % @multitable @columnfractions .11 .89 - % @item @code{#} - % @tab Legal holiday which is valid in major parts of the whole country. - % Is automatically provided with highlighting sequences respectively marking - % characters. - \noindent\ignorespaces##\unskip\multistrut}\cr -} - -\def\setmultitablespacing{% test to see if user has set \multitablelinespace. -% If so, do nothing. If not, give it an appropriate dimension based on -% current baselineskip. -\ifdim\multitablelinespace=0pt -\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip -\global\advance\multitablelinespace by-\ht0 -%% strut to put in table in case some entry doesn't have descenders, -%% to keep lines equally spaced -\let\multistrut = \strut -\else -%% FIXME: what is \box0 supposed to be? -\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 -width0pt\relax} \fi -%% Test to see if parskip is larger than space between lines of -%% table. If not, do nothing. -%% If so, set to same dimension as multitablelinespace. -\ifdim\multitableparskip>\multitablelinespace -\global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. -\fi% -\ifdim\multitableparskip=0pt -\global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. -\fi} - - -\message{conditionals,} -% Prevent errors for section commands. -% Used in @ignore and in failing conditionals. -\def\ignoresections{% - \let\chapter=\relax - \let\unnumbered=\relax - \let\top=\relax - \let\unnumberedsec=\relax - \let\unnumberedsection=\relax - \let\unnumberedsubsec=\relax - \let\unnumberedsubsection=\relax - \let\unnumberedsubsubsec=\relax - \let\unnumberedsubsubsection=\relax - \let\section=\relax - \let\subsec=\relax - \let\subsubsec=\relax - \let\subsection=\relax - \let\subsubsection=\relax - \let\appendix=\relax - \let\appendixsec=\relax - \let\appendixsection=\relax - \let\appendixsubsec=\relax - \let\appendixsubsection=\relax - \let\appendixsubsubsec=\relax - \let\appendixsubsubsection=\relax - \let\contents=\relax - \let\smallbook=\relax - \let\titlepage=\relax -} - -% Used in nested conditionals, where we have to parse the Texinfo source -% and so want to turn off most commands, in case they are used -% incorrectly. -% -\def\ignoremorecommands{% - \let\defcodeindex = \relax - \let\defcv = \relax - \let\deffn = \relax - \let\deffnx = \relax - \let\defindex = \relax - \let\defivar = \relax - \let\defmac = \relax - \let\defmethod = \relax - \let\defop = \relax - \let\defopt = \relax - \let\defspec = \relax - \let\deftp = \relax - \let\deftypefn = \relax - \let\deftypefun = \relax - \let\deftypeivar = \relax - \let\deftypeop = \relax - \let\deftypevar = \relax - \let\deftypevr = \relax - \let\defun = \relax - \let\defvar = \relax - \let\defvr = \relax - \let\ref = \relax - \let\xref = \relax - \let\printindex = \relax - \let\pxref = \relax - \let\settitle = \relax - \let\setchapternewpage = \relax - \let\setchapterstyle = \relax - \let\everyheading = \relax - \let\evenheading = \relax - \let\oddheading = \relax - \let\everyfooting = \relax - \let\evenfooting = \relax - \let\oddfooting = \relax - \let\headings = \relax - \let\include = \relax - \let\lowersections = \relax - \let\down = \relax - \let\raisesections = \relax - \let\up = \relax - \let\set = \relax - \let\clear = \relax - \let\item = \relax -} - -% Ignore @ignore ... @end ignore. -% -\def\ignore{\doignore{ignore}} - -% Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. -% -\def\ifinfo{\doignore{ifinfo}} -\def\ifhtml{\doignore{ifhtml}} -\def\ifnottex{\doignore{ifnottex}} -\def\html{\doignore{html}} -\def\menu{\doignore{menu}} -\def\direntry{\doignore{direntry}} - -% @dircategory CATEGORY -- specify a category of the dir file -% which this file should belong to. Ignore this in TeX. -\let\dircategory = \comment - -% Ignore text until a line `@end #1'. -% -\def\doignore#1{\begingroup - % Don't complain about control sequences we have declared \outer. - \ignoresections - % - % Define a command to swallow text until we reach `@end #1'. - % This @ is a catcode 12 token (that is the normal catcode of @ in - % this texinfo.tex file). We change the catcode of @ below to match. - \long\def\doignoretext##1@end #1{\enddoignore}% - % - % Make sure that spaces turn into tokens that match what \doignoretext wants. - \catcode32 = 10 - % - % Ignore braces, too, so mismatched braces don't cause trouble. - \catcode`\{ = 9 - \catcode`\} = 9 - % - % We must not have @c interpreted as a control sequence. - \catcode`\@ = 12 - % - % Make the letter c a comment character so that the rest of the line - % will be ignored. This way, the document can have (for example) - % @c @end ifinfo - % and the @end ifinfo will be properly ignored. - % (We've just changed @ to catcode 12.) - \catcode`\c = 14 - % - % And now expand that command. - \doignoretext -} - -% What we do to finish off ignored text. -% -\def\enddoignore{\endgroup\ignorespaces}% - -\newif\ifwarnedobs\warnedobsfalse -\def\obstexwarn{% - \ifwarnedobs\relax\else - % We need to warn folks that they may have trouble with TeX 3.0. - % This uses \immediate\write16 rather than \message to get newlines. - \immediate\write16{} - \immediate\write16{WARNING: for users of Unix TeX 3.0!} - \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} - \immediate\write16{If you are running another version of TeX, relax.} - \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} - \immediate\write16{ Then upgrade your TeX installation if you can.} - \immediate\write16{ (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)} - \immediate\write16{If you are stuck with version 3.0, run the} - \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} - \immediate\write16{ to use a workaround.} - \immediate\write16{} - \global\warnedobstrue - \fi -} - -% **In TeX 3.0, setting text in \nullfont hangs tex. For a -% workaround (which requires the file ``dummy.tfm'' to be installed), -% uncomment the following line: -%%%%%\font\nullfont=dummy\let\obstexwarn=\relax - -% Ignore text, except that we keep track of conditional commands for -% purposes of nesting, up to an `@end #1' command. -% -\def\nestedignore#1{% - \obstexwarn - % We must actually expand the ignored text to look for the @end - % command, so that nested ignore constructs work. Thus, we put the - % text into a \vbox and then do nothing with the result. To minimize - % the change of memory overflow, we follow the approach outlined on - % page 401 of the TeXbook: make the current font be a dummy font. - % - \setbox0 = \vbox\bgroup - % Don't complain about control sequences we have declared \outer. - \ignoresections - % - % Define `@end #1' to end the box, which will in turn undefine the - % @end command again. - \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% - % - % We are going to be parsing Texinfo commands. Most cause no - % trouble when they are used incorrectly, but some commands do - % complicated argument parsing or otherwise get confused, so we - % undefine them. - % - % We can't do anything about stray @-signs, unfortunately; - % they'll produce `undefined control sequence' errors. - \ignoremorecommands - % - % Set the current font to be \nullfont, a TeX primitive, and define - % all the font commands to also use \nullfont. We don't use - % dummy.tfm, as suggested in the TeXbook, because not all sites - % might have that installed. Therefore, math mode will still - % produce output, but that should be an extremely small amount of - % stuff compared to the main input. - % - \nullfont - \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont - \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont - \let\tensf=\nullfont - % Similarly for index fonts (mostly for their use in smallexample). - \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont - \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont - \let\smallsf=\nullfont - % - % Don't complain when characters are missing from the fonts. - \tracinglostchars = 0 - % - % Don't bother to do space factor calculations. - \frenchspacing - % - % Don't report underfull hboxes. - \hbadness = 10000 - % - % Do minimal line-breaking. - \pretolerance = 10000 - % - % Do not execute instructions in @tex - \def\tex{\doignore{tex}}% - % Do not execute macro definitions. - % `c' is a comment character, so the word `macro' will get cut off. - \def\macro{\doignore{ma}}% -} - -% @set VAR sets the variable VAR to an empty value. -% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. -% -% Since we want to separate VAR from REST-OF-LINE (which might be -% empty), we can't just use \parsearg; we have to insert a space of our -% own to delimit the rest of the line, and then take it out again if we -% didn't need it. Make sure the catcode of space is correct to avoid -% losing inside @example, for instance. -% -\def\set{\begingroup\catcode` =10 - \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. - \parsearg\setxxx} -\def\setxxx#1{\setyyy#1 \endsetyyy} -\def\setyyy#1 #2\endsetyyy{% - \def\temp{#2}% - \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty - \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. - \fi - \endgroup -} -% Can't use \xdef to pre-expand #2 and save some time, since \temp or -% \next or other control sequences that we've defined might get us into -% an infinite loop. Consider `@set foo @cite{bar}'. -\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} - -% @clear VAR clears (i.e., unsets) the variable VAR. -% -\def\clear{\parsearg\clearxxx} -\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} - -% @value{foo} gets the text saved in variable foo. -{ - \catcode`\_ = \active - % - % We might end up with active _ or - characters in the argument if - % we're called from @code, as @code{@value{foo-bar_}}. So \let any - % such active characters to their normal equivalents. - \gdef\value{\begingroup - \catcode`\-=12 \catcode`\_=12 - \indexbreaks \let_\normalunderscore - \valuexxx} -} -\def\valuexxx#1{\expandablevalue{#1}\endgroup} - -% We have this subroutine so that we can handle at least some @value's -% properly in indexes (we \let\value to this in \indexdummies). Ones -% whose names contain - or _ still won't work, but we can't do anything -% about that. The command has to be fully expandable, since the result -% winds up in the index file. This means that if the variable's value -% contains other Texinfo commands, it's almost certain it will fail -% (although perhaps we could fix that with sufficient work to do a -% one-level expansion on the result, instead of complete). -% -\def\expandablevalue#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - {[No value for ``#1'']}% - \else - \csname SET#1\endcsname - \fi -} - -% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined -% with @set. -% -\def\ifset{\parsearg\ifsetxxx} -\def\ifsetxxx #1{% - \expandafter\ifx\csname SET#1\endcsname\relax - \expandafter\ifsetfail - \else - \expandafter\ifsetsucceed - \fi -} -\def\ifsetsucceed{\conditionalsucceed{ifset}} -\def\ifsetfail{\nestedignore{ifset}} -\defineunmatchedend{ifset} - -% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been -% defined with @set, or has been undefined with @clear. -% -\def\ifclear{\parsearg\ifclearxxx} -\def\ifclearxxx #1{% - \expandafter\ifx\csname SET#1\endcsname\relax - \expandafter\ifclearsucceed - \else - \expandafter\ifclearfail - \fi -} -\def\ifclearsucceed{\conditionalsucceed{ifclear}} -\def\ifclearfail{\nestedignore{ifclear}} -\defineunmatchedend{ifclear} - -% @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text -% following, through the first @end iftex (etc.). Make `@end iftex' -% (etc.) valid only after an @iftex. -% -\def\iftex{\conditionalsucceed{iftex}} -\def\ifnothtml{\conditionalsucceed{ifnothtml}} -\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} -\defineunmatchedend{iftex} -\defineunmatchedend{ifnothtml} -\defineunmatchedend{ifnotinfo} - -% We can't just want to start a group at @iftex (for example) and end it -% at @end iftex, since then @set commands inside the conditional have no -% effect (they'd get reverted at the end of the group). So we must -% define \Eiftex to redefine itself to be its previous value. (We can't -% just define it to fail again with an ``unmatched end'' error, since -% the @ifset might be nested.) -% -\def\conditionalsucceed#1{% - \edef\temp{% - % Remember the current value of \E#1. - \let\nece{prevE#1} = \nece{E#1}% - % - % At the `@end #1', redefine \E#1 to be its previous value. - \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% - }% - \temp -} - -% We need to expand lots of \csname's, but we don't want to expand the -% control sequences after we've constructed them. -% -\def\nece#1{\expandafter\noexpand\csname#1\endcsname} - -% @defininfoenclose. -\let\definfoenclose=\comment - - -\message{indexing,} -% Index generation facilities - -% Define \newwrite to be identical to plain tex's \newwrite -% except not \outer, so it can be used within \newindex. -{\catcode`\@=11 -\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} - -% \newindex {foo} defines an index named foo. -% It automatically defines \fooindex such that -% \fooindex ...rest of line... puts an entry in the index foo. -% It also defines \fooindfile to be the number of the output channel for -% the file that accumulates this index. The file's extension is foo. -% The name of an index should be no more than 2 characters long -% for the sake of vms. -% -\def\newindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 % Open the file - \fi - \expandafter\xdef\csname#1index\endcsname{% % Define @#1index - \noexpand\doindex{#1}} -} - -% @defindex foo == \newindex{foo} - -\def\defindex{\parsearg\newindex} - -% Define @defcodeindex, like @defindex except put all entries in @code. - -\def\newcodeindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 - \fi - \expandafter\xdef\csname#1index\endcsname{% - \noexpand\docodeindex{#1}} -} - -\def\defcodeindex{\parsearg\newcodeindex} - -% @synindex foo bar makes index foo feed into index bar. -% Do this instead of @defindex foo if you don't want it as a separate index. -% The \closeout helps reduce unnecessary open files; the limit on the -% Acorn RISC OS is a mere 16 files. -\def\synindex#1 #2 {% - \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname - \expandafter\closeout\csname#1indfile\endcsname - \expandafter\let\csname#1indfile\endcsname=\synindexfoo - \expandafter\xdef\csname#1index\endcsname{% define \xxxindex - \noexpand\doindex{#2}}% -} - -% @syncodeindex foo bar similar, but put all entries made for index foo -% inside @code. -\def\syncodeindex#1 #2 {% - \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname - \expandafter\closeout\csname#1indfile\endcsname - \expandafter\let\csname#1indfile\endcsname=\synindexfoo - \expandafter\xdef\csname#1index\endcsname{% define \xxxindex - \noexpand\docodeindex{#2}}% -} - -% Define \doindex, the driver for all \fooindex macros. -% Argument #1 is generated by the calling \fooindex macro, -% and it is "foo", the name of the index. - -% \doindex just uses \parsearg; it calls \doind for the actual work. -% This is because \doind is more useful to call from other macros. - -% There is also \dosubind {index}{topic}{subtopic} -% which makes an entry in a two-level index such as the operation index. - -\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} -\def\singleindexer #1{\doind{\indexname}{#1}} - -% like the previous two, but they put @code around the argument. -\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} -\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} - -\def\indexdummies{% -\def\ { }% -% Take care of the plain tex accent commands. -\def\"{\realbackslash "}% -\def\`{\realbackslash `}% -\def\'{\realbackslash '}% -\def\^{\realbackslash ^}% -\def\~{\realbackslash ~}% -\def\={\realbackslash =}% -\def\b{\realbackslash b}% -\def\c{\realbackslash c}% -\def\d{\realbackslash d}% -\def\u{\realbackslash u}% -\def\v{\realbackslash v}% -\def\H{\realbackslash H}% -% Take care of the plain tex special European modified letters. -\def\oe{\realbackslash oe}% -\def\ae{\realbackslash ae}% -\def\aa{\realbackslash aa}% -\def\OE{\realbackslash OE}% -\def\AE{\realbackslash AE}% -\def\AA{\realbackslash AA}% -\def\o{\realbackslash o}% -\def\O{\realbackslash O}% -\def\l{\realbackslash l}% -\def\L{\realbackslash L}% -\def\ss{\realbackslash ss}% -% Take care of texinfo commands likely to appear in an index entry. -% (Must be a way to avoid doing expansion at all, and thus not have to -% laboriously list every single command here.) -\def\@{@}% will be @@ when we switch to @ as escape char. -% Need these in case \tex is in effect and \{ is a \delimiter again. -% But can't use \lbracecmd and \rbracecmd because texindex assumes -% braces and backslashes are used only as delimiters. -\let\{ = \mylbrace -\let\} = \myrbrace -\def\_{{\realbackslash _}}% -\def\w{\realbackslash w }% -\def\bf{\realbackslash bf }% -%\def\rm{\realbackslash rm }% -\def\sl{\realbackslash sl }% -\def\sf{\realbackslash sf}% -\def\tt{\realbackslash tt}% -\def\gtr{\realbackslash gtr}% -\def\less{\realbackslash less}% -\def\hat{\realbackslash hat}% -\def\TeX{\realbackslash TeX}% -\def\dots{\realbackslash dots }% -\def\result{\realbackslash result}% -\def\equiv{\realbackslash equiv}% -\def\expansion{\realbackslash expansion}% -\def\print{\realbackslash print}% -\def\error{\realbackslash error}% -\def\point{\realbackslash point}% -\def\copyright{\realbackslash copyright}% -\def\tclose##1{\realbackslash tclose {##1}}% -\def\code##1{\realbackslash code {##1}}% -\def\uref##1{\realbackslash uref {##1}}% -\def\url##1{\realbackslash url {##1}}% -\def\env##1{\realbackslash env {##1}}% -\def\command##1{\realbackslash command {##1}}% -\def\option##1{\realbackslash option {##1}}% -\def\dotless##1{\realbackslash dotless {##1}}% -\def\samp##1{\realbackslash samp {##1}}% -\def\,##1{\realbackslash ,{##1}}% -\def\t##1{\realbackslash t {##1}}% -\def\r##1{\realbackslash r {##1}}% -\def\i##1{\realbackslash i {##1}}% -\def\b##1{\realbackslash b {##1}}% -\def\sc##1{\realbackslash sc {##1}}% -\def\cite##1{\realbackslash cite {##1}}% -\def\key##1{\realbackslash key {##1}}% -\def\file##1{\realbackslash file {##1}}% -\def\var##1{\realbackslash var {##1}}% -\def\kbd##1{\realbackslash kbd {##1}}% -\def\dfn##1{\realbackslash dfn {##1}}% -\def\emph##1{\realbackslash emph {##1}}% -\def\acronym##1{\realbackslash acronym {##1}}% -% -% Handle some cases of @value -- where the variable name does not -% contain - or _, and the value does not contain any -% (non-fully-expandable) commands. -\let\value = \expandablevalue -% -\unsepspaces -% Turn off macro expansion -\turnoffmacros -} - -% If an index command is used in an @example environment, any spaces -% therein should become regular spaces in the raw index file, not the -% expansion of \tie (\\leavevmode \penalty \@M \ ). -{\obeyspaces - \gdef\unsepspaces{\obeyspaces\let =\space}} - -% \indexnofonts no-ops all font-change commands. -% This is used when outputting the strings to sort the index by. -\def\indexdummyfont#1{#1} -\def\indexdummytex{TeX} -\def\indexdummydots{...} - -\def\indexnofonts{% -% Just ignore accents. -\let\,=\indexdummyfont -\let\"=\indexdummyfont -\let\`=\indexdummyfont -\let\'=\indexdummyfont -\let\^=\indexdummyfont -\let\~=\indexdummyfont -\let\==\indexdummyfont -\let\b=\indexdummyfont -\let\c=\indexdummyfont -\let\d=\indexdummyfont -\let\u=\indexdummyfont -\let\v=\indexdummyfont -\let\H=\indexdummyfont -\let\dotless=\indexdummyfont -% Take care of the plain tex special European modified letters. -\def\oe{oe}% -\def\ae{ae}% -\def\aa{aa}% -\def\OE{OE}% -\def\AE{AE}% -\def\AA{AA}% -\def\o{o}% -\def\O{O}% -\def\l{l}% -\def\L{L}% -\def\ss{ss}% -\let\w=\indexdummyfont -\let\t=\indexdummyfont -\let\r=\indexdummyfont -\let\i=\indexdummyfont -\let\b=\indexdummyfont -\let\emph=\indexdummyfont -\let\strong=\indexdummyfont -\let\cite=\indexdummyfont -\let\sc=\indexdummyfont -%Don't no-op \tt, since it isn't a user-level command -% and is used in the definitions of the active chars like <, >, |... -%\let\tt=\indexdummyfont -\let\tclose=\indexdummyfont -\let\code=\indexdummyfont -\let\url=\indexdummyfont -\let\uref=\indexdummyfont -\let\env=\indexdummyfont -\let\acronym=\indexdummyfont -\let\command=\indexdummyfont -\let\option=\indexdummyfont -\let\file=\indexdummyfont -\let\samp=\indexdummyfont -\let\kbd=\indexdummyfont -\let\key=\indexdummyfont -\let\var=\indexdummyfont -\let\TeX=\indexdummytex -\let\dots=\indexdummydots -\def\@{@}% -} - -% To define \realbackslash, we must make \ not be an escape. -% We must first make another character (@) an escape -% so we do not become unable to do a definition. - -{\catcode`\@=0 \catcode`\\=\other - @gdef@realbackslash{\}} - -\let\indexbackslash=0 %overridden during \printindex. -\let\SETmarginindex=\relax % put index entries in margin (undocumented)? - -% For \ifx comparisons. -\def\emptymacro{\empty} - -% Most index entries go through here, but \dosubind is the general case. -% -\def\doind#1#2{\dosubind{#1}{#2}\empty} - -% Workhorse for all \fooindexes. -% #1 is name of index, #2 is stuff to put there, #3 is subentry -- -% \empty if called from \doind, as we usually are. The main exception -% is with defuns, which call us directly. -% -\def\dosubind#1#2#3{% - % Put the index entry in the margin if desired. - \ifx\SETmarginindex\relax\else - \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% - \fi - {% - \count255=\lastpenalty - {% - \indexdummies % Must do this here, since \bf, etc expand at this stage - \escapechar=`\\ - {% - \let\folio = 0% We will expand all macros now EXCEPT \folio. - \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now - % so it will be output as is; and it will print as backslash. - % - \def\thirdarg{#3}% - % - % If third arg is present, precede it with space in sort key. - \ifx\thirdarg\emptymacro - \let\subentry = \empty - \else - \def\subentry{ #3}% - \fi - % - % First process the index entry with all font commands turned - % off to get the string to sort by. - {\indexnofonts \xdef\indexsorttmp{#2\subentry}}% - % - % Now the real index entry with the fonts. - \toks0 = {#2}% - % - % If third (subentry) arg is present, add it to the index - % string. And include a space. - \ifx\thirdarg\emptymacro \else - \toks0 = \expandafter{\the\toks0 \space #3}% - \fi - % - % Set up the complete index entry, with both the sort key - % and the original text, including any font commands. We write - % three arguments to \entry to the .?? file, texindex reduces to - % two when writing the .??s sorted result. - \edef\temp{% - \write\csname#1indfile\endcsname{% - \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% - }% - % - % If a skip is the last thing on the list now, preserve it - % by backing up by \lastskip, doing the \write, then inserting - % the skip again. Otherwise, the whatsit generated by the - % \write will make \lastskip zero. The result is that sequences - % like this: - % @end defun - % @tindex whatever - % @defun ... - % will have extra space inserted, because the \medbreak in the - % start of the @defun won't see the skip inserted by the @end of - % the previous defun. - % - % But don't do any of this if we're not in vertical mode. We - % don't want to do a \vskip and prematurely end a paragraph. - % - % Avoid page breaks due to these extra skips, too. - % - \iflinks - \ifvmode - \skip0 = \lastskip - \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi - \fi - % - \temp % do the write - % - % - \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi - \fi - }% - }% - \penalty\count255 - }% -} - -% The index entry written in the file actually looks like -% \entry {sortstring}{page}{topic} -% or -% \entry {sortstring}{page}{topic}{subtopic} -% The texindex program reads in these files and writes files -% containing these kinds of lines: -% \initial {c} -% before the first topic whose initial is c -% \entry {topic}{pagelist} -% for a topic that is used without subtopics -% \primary {topic} -% for the beginning of a topic that is used with subtopics -% \secondary {subtopic}{pagelist} -% for each subtopic. - -% Define the user-accessible indexing commands -% @findex, @vindex, @kindex, @cindex. - -\def\findex {\fnindex} -\def\kindex {\kyindex} -\def\cindex {\cpindex} -\def\vindex {\vrindex} -\def\tindex {\tpindex} -\def\pindex {\pgindex} - -\def\cindexsub {\begingroup\obeylines\cindexsub} -{\obeylines % -\gdef\cindexsub "#1" #2^^M{\endgroup % -\dosubind{cp}{#2}{#1}}} - -% Define the macros used in formatting output of the sorted index material. - -% @printindex causes a particular index (the ??s file) to get printed. -% It does not print any chapter heading (usually an @unnumbered). -% -\def\printindex{\parsearg\doprintindex} -\def\doprintindex#1{\begingroup - \dobreak \chapheadingskip{10000}% - % - \smallfonts \rm - \tolerance = 9500 - \indexbreaks - % - % See if the index file exists and is nonempty. - % Change catcode of @ here so that if the index file contains - % \initial {@} - % as its first line, TeX doesn't complain about mismatched braces - % (because it thinks @} is a control sequence). - \catcode`\@ = 11 - \openin 1 \jobname.#1s - \ifeof 1 - % \enddoublecolumns gets confused if there is no text in the index, - % and it loses the chapter title and the aux file entries for the - % index. The easiest way to prevent this problem is to make sure - % there is some text. - \putwordIndexNonexistent - \else - % - % If the index file exists but is empty, then \openin leaves \ifeof - % false. We have to make TeX try to read something from the file, so - % it can discover if there is anything in it. - \read 1 to \temp - \ifeof 1 - \putwordIndexIsEmpty - \else - % Index files are almost Texinfo source, but we use \ as the escape - % character. It would be better to use @, but that's too big a change - % to make right now. - \def\indexbackslash{\rawbackslashxx}% - \catcode`\\ = 0 - \escapechar = `\\ - \begindoublecolumns - \input \jobname.#1s - \enddoublecolumns - \fi - \fi - \closein 1 -\endgroup} - -% These macros are used by the sorted index file itself. -% Change them to control the appearance of the index. - -\def\initial#1{{% - % Some minor font changes for the special characters. - \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt - % - % Remove any glue we may have, we'll be inserting our own. - \removelastskip - % - % We like breaks before the index initials, so insert a bonus. - \penalty -300 - % - % Typeset the initial. Making this add up to a whole number of - % baselineskips increases the chance of the dots lining up from column - % to column. It still won't often be perfect, because of the stretch - % we need before each entry, but it's better. - % - % No shrink because it confuses \balancecolumns. - \vskip 1.67\baselineskip plus .5\baselineskip - \leftline{\secbf #1}% - \vskip .33\baselineskip plus .1\baselineskip - % - % Do our best not to break after the initial. - \nobreak -}} - -% This typesets a paragraph consisting of #1, dot leaders, and then #2 -% flush to the right margin. It is used for index and table of contents -% entries. The paragraph is indented by \leftskip. -% -\def\entry#1#2{\begingroup - % - % Start a new paragraph if necessary, so our assignments below can't - % affect previous text. - \par - % - % Do not fill out the last line with white space. - \parfillskip = 0in - % - % No extra space above this paragraph. - \parskip = 0in - % - % Do not prefer a separate line ending with a hyphen to fewer lines. - \finalhyphendemerits = 0 - % - % \hangindent is only relevant when the entry text and page number - % don't both fit on one line. In that case, bob suggests starting the - % dots pretty far over on the line. Unfortunately, a large - % indentation looks wrong when the entry text itself is broken across - % lines. So we use a small indentation and put up with long leaders. - % - % \hangafter is reset to 1 (which is the value we want) at the start - % of each paragraph, so we need not do anything with that. - \hangindent = 2em - % - % When the entry text needs to be broken, just fill out the first line - % with blank space. - \rightskip = 0pt plus1fil - % - % A bit of stretch before each entry for the benefit of balancing columns. - \vskip 0pt plus1pt - % - % Start a ``paragraph'' for the index entry so the line breaking - % parameters we've set above will have an effect. - \noindent - % - % Insert the text of the index entry. TeX will do line-breaking on it. - #1% - % The following is kludged to not output a line of dots in the index if - % there are no page numbers. The next person who breaks this will be - % cursed by a Unix daemon. - \def\tempa{{\rm }}% - \def\tempb{#2}% - \edef\tempc{\tempa}% - \edef\tempd{\tempb}% - \ifx\tempc\tempd\ \else% - % - % If we must, put the page number on a line of its own, and fill out - % this line with blank space. (The \hfil is overwhelmed with the - % fill leaders glue in \indexdotfill if the page number does fit.) - \hfil\penalty50 - \null\nobreak\indexdotfill % Have leaders before the page number. - % - % The `\ ' here is removed by the implicit \unskip that TeX does as - % part of (the primitive) \par. Without it, a spurious underfull - % \hbox ensues. - \ifpdf - \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. - \else - \ #2% The page number ends the paragraph. - \fi - \fi% - \par -\endgroup} - -% Like \dotfill except takes at least 1 em. -\def\indexdotfill{\cleaders - \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} - -\def\primary #1{\line{#1\hfil}} - -\newskip\secondaryindent \secondaryindent=0.5cm - -\def\secondary #1#2{ -{\parfillskip=0in \parskip=0in -\hangindent =1in \hangafter=1 -\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par -}} - -% Define two-column mode, which we use to typeset indexes. -% Adapted from the TeXbook, page 416, which is to say, -% the manmac.tex format used to print the TeXbook itself. -\catcode`\@=11 - -\newbox\partialpage -\newdimen\doublecolumnhsize - -\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns - % Grab any single-column material above us. - \output = {% - % - % Here is a possibility not foreseen in manmac: if we accumulate a - % whole lot of material, we might end up calling this \output - % routine twice in a row (see the doublecol-lose test, which is - % essentially a couple of indexes with @setchapternewpage off). In - % that case we just ship out what is in \partialpage with the normal - % output routine. Generally, \partialpage will be empty when this - % runs and this will be a no-op. See the indexspread.tex test case. - \ifvoid\partialpage \else - \onepageout{\pagecontents\partialpage}% - \fi - % - \global\setbox\partialpage = \vbox{% - % Unvbox the main output page. - \unvbox\PAGE - \kern-\topskip \kern\baselineskip - }% - }% - \eject % run that output routine to set \partialpage - % - % Use the double-column output routine for subsequent pages. - \output = {\doublecolumnout}% - % - % Change the page size parameters. We could do this once outside this - % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 - % format, but then we repeat the same computation. Repeating a couple - % of assignments once per index is clearly meaningless for the - % execution time, so we may as well do it in one place. - % - % First we halve the line length, less a little for the gutter between - % the columns. We compute the gutter based on the line length, so it - % changes automatically with the paper format. The magic constant - % below is chosen so that the gutter has the same value (well, +-<1pt) - % as it did when we hard-coded it. - % - % We put the result in a separate register, \doublecolumhsize, so we - % can restore it in \pagesofar, after \hsize itself has (potentially) - % been clobbered. - % - \doublecolumnhsize = \hsize - \advance\doublecolumnhsize by -.04154\hsize - \divide\doublecolumnhsize by 2 - \hsize = \doublecolumnhsize - % - % Double the \vsize as well. (We don't need a separate register here, - % since nobody clobbers \vsize.) - \advance\vsize by -\ht\partialpage - \vsize = 2\vsize -} - -% The double-column output routine for all double-column pages except -% the last. -% -\def\doublecolumnout{% - \splittopskip=\topskip \splitmaxdepth=\maxdepth - % Get the available space for the double columns -- the normal - % (undoubled) page height minus any material left over from the - % previous page. - \dimen@ = \vsize - \divide\dimen@ by 2 - % - % box0 will be the left-hand column, box2 the right. - \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ - \onepageout\pagesofar - \unvbox255 - \penalty\outputpenalty -} -\def\pagesofar{% - % Re-output the contents of the output page -- any previous material, - % followed by the two boxes we just split, in box0 and box2. - \unvbox\partialpage - % - \hsize = \doublecolumnhsize - \wd0=\hsize \wd2=\hsize - \hbox to\pagewidth{\box0\hfil\box2}% -} -\def\enddoublecolumns{% - \output = {% - % Split the last of the double-column material. Leave it on the - % current page, no automatic page break. - \balancecolumns - % - % If we end up splitting too much material for the current page, - % though, there will be another page break right after this \output - % invocation ends. Having called \balancecolumns once, we do not - % want to call it again. Therefore, reset \output to its normal - % definition right away. (We hope \balancecolumns will never be - % called on to balance too much material, but if it is, this makes - % the output somewhat more palatable.) - \global\output = {\onepageout{\pagecontents\PAGE}}% - }% - \eject - \endgroup % started in \begindoublecolumns - % - % \pagegoal was set to the doubled \vsize above, since we restarted - % the current page. We're now back to normal single-column - % typesetting, so reset \pagegoal to the normal \vsize (after the - % \endgroup where \vsize got restored). - \pagegoal = \vsize -} -\def\balancecolumns{% - % Called at the end of the double column material. - \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. - \dimen@ = \ht0 - \advance\dimen@ by \topskip - \advance\dimen@ by-\baselineskip - \divide\dimen@ by 2 % target to split to - %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% - \splittopskip = \topskip - % Loop until we get a decent breakpoint. - {% - \vbadness = 10000 - \loop - \global\setbox3 = \copy0 - \global\setbox1 = \vsplit3 to \dimen@ - \ifdim\ht3>\dimen@ - \global\advance\dimen@ by 1pt - \repeat - }% - %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% - \setbox0=\vbox to\dimen@{\unvbox1}% - \setbox2=\vbox to\dimen@{\unvbox3}% - % - \pagesofar -} -\catcode`\@ = \other - - -\message{sectioning,} -% Chapters, sections, etc. - -\newcount\chapno -\newcount\secno \secno=0 -\newcount\subsecno \subsecno=0 -\newcount\subsubsecno \subsubsecno=0 - -% This counter is funny since it counts through charcodes of letters A, B, ... -\newcount\appendixno \appendixno = `\@ -% \def\appendixletter{\char\the\appendixno} -% We do the following for the sake of pdftex, which needs the actual -% letter in the expansion, not just typeset. -\def\appendixletter{% - \ifnum\appendixno=`A A% - \else\ifnum\appendixno=`B B% - \else\ifnum\appendixno=`C C% - \else\ifnum\appendixno=`D D% - \else\ifnum\appendixno=`E E% - \else\ifnum\appendixno=`F F% - \else\ifnum\appendixno=`G G% - \else\ifnum\appendixno=`H H% - \else\ifnum\appendixno=`I I% - \else\ifnum\appendixno=`J J% - \else\ifnum\appendixno=`K K% - \else\ifnum\appendixno=`L L% - \else\ifnum\appendixno=`M M% - \else\ifnum\appendixno=`N N% - \else\ifnum\appendixno=`O O% - \else\ifnum\appendixno=`P P% - \else\ifnum\appendixno=`Q Q% - \else\ifnum\appendixno=`R R% - \else\ifnum\appendixno=`S S% - \else\ifnum\appendixno=`T T% - \else\ifnum\appendixno=`U U% - \else\ifnum\appendixno=`V V% - \else\ifnum\appendixno=`W W% - \else\ifnum\appendixno=`X X% - \else\ifnum\appendixno=`Y Y% - \else\ifnum\appendixno=`Z Z% - % The \the is necessary, despite appearances, because \appendixletter is - % expanded while writing the .toc file. \char\appendixno is not - % expandable, thus it is written literally, thus all appendixes come out - % with the same letter (or @) in the toc without it. - \else\char\the\appendixno - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} - -% Each @chapter defines this as the name of the chapter. -% page headings and footings can use it. @section does likewise. -\def\thischapter{} -\def\thissection{} - -\newcount\absseclevel % used to calculate proper heading level -\newcount\secbase\secbase=0 % @raise/lowersections modify this count - -% @raisesections: treat @section as chapter, @subsection as section, etc. -\def\raisesections{\global\advance\secbase by -1} -\let\up=\raisesections % original BFox name - -% @lowersections: treat @chapter as section, @section as subsection, etc. -\def\lowersections{\global\advance\secbase by 1} -\let\down=\lowersections % original BFox name - -% Choose a numbered-heading macro -% #1 is heading level if unmodified by @raisesections or @lowersections -% #2 is text for heading -\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \chapterzzz{#2} -\or - \seczzz{#2} -\or - \numberedsubseczzz{#2} -\or - \numberedsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \chapterzzz{#2} - \else - \numberedsubsubseczzz{#2} - \fi -\fi -} - -% like \numhead, but chooses appendix heading levels -\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \appendixzzz{#2} -\or - \appendixsectionzzz{#2} -\or - \appendixsubseczzz{#2} -\or - \appendixsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \appendixzzz{#2} - \else - \appendixsubsubseczzz{#2} - \fi -\fi -} - -% like \numhead, but chooses numberless heading levels -\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \unnumberedzzz{#2} -\or - \unnumberedseczzz{#2} -\or - \unnumberedsubseczzz{#2} -\or - \unnumberedsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \unnumberedzzz{#2} - \else - \unnumberedsubsubseczzz{#2} - \fi -\fi -} - -% @chapter, @appendix, @unnumbered. -\def\thischaptername{No Chapter Title} -\outer\def\chapter{\parsearg\chapteryyy} -\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz -\def\chapterzzz #1{% -\secno=0 \subsecno=0 \subsubsecno=0 -\global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% -\chapmacro {#1}{\the\chapno}% -\gdef\thissection{#1}% -\gdef\thischaptername{#1}% -% We don't substitute the actual chapter name into \thischapter -% because we don't want its macros evaluated now. -\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% - {\the\chapno}}}% -\temp -\donoderef -\global\let\section = \numberedsec -\global\let\subsection = \numberedsubsec -\global\let\subsubsection = \numberedsubsubsec -} - -\outer\def\appendix{\parsearg\appendixyyy} -\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz -\def\appendixzzz #1{% -\secno=0 \subsecno=0 \subsubsecno=0 -\global\advance \appendixno by 1 -\message{\putwordAppendix\space \appendixletter}% -\chapmacro {#1}{\putwordAppendix{} \appendixletter}% -\gdef\thissection{#1}% -\gdef\thischaptername{#1}% -\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% - {\putwordAppendix{} \appendixletter}}}% -\temp -\appendixnoderef -\global\let\section = \appendixsec -\global\let\subsection = \appendixsubsec -\global\let\subsubsection = \appendixsubsubsec -} - -% @centerchap is like @unnumbered, but the heading is centered. -\outer\def\centerchap{\parsearg\centerchapyyy} -\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} - -% @top is like @unnumbered. -\outer\def\top{\parsearg\unnumberedyyy} - -\outer\def\unnumbered{\parsearg\unnumberedyyy} -\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz -\def\unnumberedzzz #1{% -\secno=0 \subsecno=0 \subsubsecno=0 -% -% This used to be simply \message{#1}, but TeX fully expands the -% argument to \message. Therefore, if #1 contained @-commands, TeX -% expanded them. For example, in `@unnumbered The @cite{Book}', TeX -% expanded @cite (which turns out to cause errors because \cite is meant -% to be executed, not expanded). -% -% Anyway, we don't want the fully-expanded definition of @cite to appear -% as a result of the \message, we just want `@cite' itself. We use -% \the to achieve this: TeX expands \the only once, -% simply yielding the contents of . (We also do this for -% the toc entries.) -\toks0 = {#1}\message{(\the\toks0)}% -% -\unnumbchapmacro {#1}% -\gdef\thischapter{#1}\gdef\thissection{#1}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}% -\temp -\unnumbnoderef -\global\let\section = \unnumberedsec -\global\let\subsection = \unnumberedsubsec -\global\let\subsubsection = \unnumberedsubsubsec -} - -% Sections. -\outer\def\numberedsec{\parsearg\secyyy} -\def\secyyy #1{\numhead1{#1}} % normally calls seczzz -\def\seczzz #1{% -\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % -\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% - {\the\chapno}{\the\secno}}}% -\temp -\donoderef -\nobreak -} - -\outer\def\appendixsection{\parsearg\appendixsecyyy} -\outer\def\appendixsec{\parsearg\appendixsecyyy} -\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz -\def\appendixsectionzzz #1{% -\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % -\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% - {\appendixletter}{\the\secno}}}% -\temp -\appendixnoderef -\nobreak -} - -\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} -\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz -\def\unnumberedseczzz #1{% -\plainsecheading {#1}\gdef\thissection{#1}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}% -\temp -\unnumbnoderef -\nobreak -} - -% Subsections. -\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} -\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz -\def\numberedsubseczzz #1{% -\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % -\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% - {\the\chapno}{\the\secno}{\the\subsecno}}}% -\temp -\donoderef -\nobreak -} - -\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} -\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz -\def\appendixsubseczzz #1{% -\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % -\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% - {\appendixletter}{\the\secno}{\the\subsecno}}}% -\temp -\appendixnoderef -\nobreak -} - -\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} -\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz -\def\unnumberedsubseczzz #1{% -\plainsubsecheading {#1}\gdef\thissection{#1}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry% - {\the\toks0}}}% -\temp -\unnumbnoderef -\nobreak -} - -% Subsubsections. -\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} -\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz -\def\numberedsubsubseczzz #1{% -\gdef\thissection{#1}\global\advance \subsubsecno by 1 % -\subsubsecheading {#1} - {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% - {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% -\temp -\donoderef -\nobreak -} - -\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} -\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz -\def\appendixsubsubseczzz #1{% -\gdef\thissection{#1}\global\advance \subsubsecno by 1 % -\subsubsecheading {#1} - {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% - {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% -\temp -\appendixnoderef -\nobreak -} - -\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} -\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz -\def\unnumberedsubsubseczzz #1{% -\plainsubsubsecheading {#1}\gdef\thissection{#1}% -\toks0 = {#1}% -\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry% - {\the\toks0}}}% -\temp -\unnumbnoderef -\nobreak -} - -% These are variants which are not "outer", so they can appear in @ifinfo. -% Actually, they should now be obsolete; ordinary section commands should work. -\def\infotop{\parsearg\unnumberedzzz} -\def\infounnumbered{\parsearg\unnumberedzzz} -\def\infounnumberedsec{\parsearg\unnumberedseczzz} -\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} -\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} - -\def\infoappendix{\parsearg\appendixzzz} -\def\infoappendixsec{\parsearg\appendixseczzz} -\def\infoappendixsubsec{\parsearg\appendixsubseczzz} -\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} - -\def\infochapter{\parsearg\chapterzzz} -\def\infosection{\parsearg\sectionzzz} -\def\infosubsection{\parsearg\subsectionzzz} -\def\infosubsubsection{\parsearg\subsubsectionzzz} - -% These macros control what the section commands do, according -% to what kind of chapter we are in (ordinary, appendix, or unnumbered). -% Define them by default for a numbered chapter. -\global\let\section = \numberedsec -\global\let\subsection = \numberedsubsec -\global\let\subsubsection = \numberedsubsubsec - -% Define @majorheading, @heading and @subheading - -% NOTE on use of \vbox for chapter headings, section headings, and such: -% 1) We use \vbox rather than the earlier \line to permit -% overlong headings to fold. -% 2) \hyphenpenalty is set to 10000 because hyphenation in a -% heading is obnoxious; this forbids it. -% 3) Likewise, headings look best if no \parindent is used, and -% if justification is not attempted. Hence \raggedright. - - -\def\majorheading{\parsearg\majorheadingzzz} -\def\majorheadingzzz #1{% -{\advance\chapheadingskip by 10pt \chapbreak }% -{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\penalty 200} - -\def\chapheading{\parsearg\chapheadingzzz} -\def\chapheadingzzz #1{\chapbreak % -{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\penalty 200} - -% @heading, @subheading, @subsubheading. -\def\heading{\parsearg\plainsecheading} -\def\subheading{\parsearg\plainsubsecheading} -\def\subsubheading{\parsearg\plainsubsubsecheading} - -% These macros generate a chapter, section, etc. heading only -% (including whitespace, linebreaking, etc. around it), -% given all the information in convenient, parsed form. - -%%% Args are the skip and penalty (usually negative) -\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} - -\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} - -%%% Define plain chapter starts, and page on/off switching for it -% Parameter controlling skip before chapter headings (if needed) - -\newskip\chapheadingskip - -\def\chapbreak{\dobreak \chapheadingskip {-4000}} -\def\chappager{\par\vfill\supereject} -\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} - -\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} - -\def\CHAPPAGoff{% -\global\let\contentsalignmacro = \chappager -\global\let\pchapsepmacro=\chapbreak -\global\let\pagealignmacro=\chappager} - -\def\CHAPPAGon{% -\global\let\contentsalignmacro = \chappager -\global\let\pchapsepmacro=\chappager -\global\let\pagealignmacro=\chappager -\global\def\HEADINGSon{\HEADINGSsingle}} - -\def\CHAPPAGodd{ -\global\let\contentsalignmacro = \chapoddpage -\global\let\pchapsepmacro=\chapoddpage -\global\let\pagealignmacro=\chapoddpage -\global\def\HEADINGSon{\HEADINGSdouble}} - -\CHAPPAGon - -\def\CHAPFplain{ -\global\let\chapmacro=\chfplain -\global\let\unnumbchapmacro=\unnchfplain -\global\let\centerchapmacro=\centerchfplain} - -% Plain chapter opening. -% #1 is the text, #2 the chapter number or empty if unnumbered. -\def\chfplain#1#2{% - \pchapsepmacro - {% - \chapfonts \rm - \def\chapnum{#2}% - \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent = \wd0 \centerparametersmaybe - \unhbox0 #1\par}% - }% - \nobreak\bigskip % no page break after a chapter title - \nobreak -} - -% Plain opening for unnumbered. -\def\unnchfplain#1{\chfplain{#1}{}} - -% @centerchap -- centered and unnumbered. -\let\centerparametersmaybe = \relax -\def\centerchfplain#1{{% - \def\centerparametersmaybe{% - \advance\rightskip by 3\rightskip - \leftskip = \rightskip - \parfillskip = 0pt - }% - \chfplain{#1}{}% -}} - -\CHAPFplain % The default - -\def\unnchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\nobreak -} - -\def\chfopen #1#2{\chapoddpage {\chapfonts -\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% -\par\penalty 5000 % -} - -\def\centerchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt - \hfill {\rm #1}\hfill}}\bigskip \par\nobreak -} - -\def\CHAPFopen{ -\global\let\chapmacro=\chfopen -\global\let\unnumbchapmacro=\unnchfopen -\global\let\centerchapmacro=\centerchfopen} - - -% Section titles. -\newskip\secheadingskip -\def\secheadingbreak{\dobreak \secheadingskip {-1000}} -\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} -\def\plainsecheading#1{\sectionheading{sec}{}{#1}} - -% Subsection titles. -\newskip \subsecheadingskip -\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} -\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} -\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} - -% Subsubsection titles. -\let\subsubsecheadingskip = \subsecheadingskip -\let\subsubsecheadingbreak = \subsecheadingbreak -\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} -\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} - - -% Print any size section title. -% -% #1 is the section type (sec/subsec/subsubsec), #2 is the section -% number (maybe empty), #3 the text. -\def\sectionheading#1#2#3{% - {% - \expandafter\advance\csname #1headingskip\endcsname by \parskip - \csname #1headingbreak\endcsname - }% - {% - % Switch to the right set of fonts. - \csname #1fonts\endcsname \rm - % - % Only insert the separating space if we have a section number. - \def\secnum{#2}% - \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% - % - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent = \wd0 % zero if no section number - \unhbox0 #3}% - }% - \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak -} - - -\message{toc,} -% Table of contents. -\newwrite\tocfile - -% Write an entry to the toc file, opening it if necessary. -% Called from @chapter, etc. We supply {\folio} at the end of the -% argument, which will end up as the last argument to the \...entry macro. -% -% We open the .toc file here instead of at @setfilename or any other -% given time so that @contents can be put in the document anywhere. -% -\newif\iftocfileopened -\def\writetocentry#1{% - \iftocfileopened\else - \immediate\openout\tocfile = \jobname.toc - \global\tocfileopenedtrue - \fi - \iflinks \write\tocfile{#1{\folio}}\fi -} - -\newskip\contentsrightmargin \contentsrightmargin=1in -\newcount\savepageno -\newcount\lastnegativepageno \lastnegativepageno = -1 - -% Finish up the main text and prepare to read what we've written -% to \tocfile. -% -\def\startcontents#1{% - % If @setchapternewpage on, and @headings double, the contents should - % start on an odd page, unlike chapters. Thus, we maintain - % \contentsalignmacro in parallel with \pagealignmacro. - % From: Torbjorn Granlund - \contentsalignmacro - \immediate\closeout\tocfile - % - % Don't need to put `Contents' or `Short Contents' in the headline. - % It is abundantly clear what they are. - \unnumbchapmacro{#1}\def\thischapter{}% - \savepageno = \pageno - \begingroup % Set up to handle contents files properly. - \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 - % We can't do this, because then an actual ^ in a section - % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. - %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi - \raggedbottom % Worry more about breakpoints than the bottom. - \advance\hsize by -\contentsrightmargin % Don't use the full line length. - % - % Roman numerals for page numbers. - \ifnum \pageno>0 \pageno = \lastnegativepageno \fi -} - - -% Normal (long) toc. -\def\contents{% - \startcontents{\putwordTOC}% - \openin 1 \jobname.toc - \ifeof 1 \else - \closein 1 - \input \jobname.toc - \fi - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \pdfmakeoutlines - \endgroup - \lastnegativepageno = \pageno - \pageno = \savepageno -} - -% And just the chapters. -\def\summarycontents{% - \startcontents{\putwordShortTOC}% - % - \let\chapentry = \shortchapentry - \let\unnumbchapentry = \shortunnumberedentry - % We want a true roman here for the page numbers. - \secfonts - \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl - \rm - \hyphenpenalty = 10000 - \advance\baselineskip by 1pt % Open it up a little. - \def\secentry ##1##2##3##4{} - \def\unnumbsecentry ##1##2{} - \def\subsecentry ##1##2##3##4##5{} - \def\unnumbsubsecentry ##1##2{} - \def\subsubsecentry ##1##2##3##4##5##6{} - \def\unnumbsubsubsecentry ##1##2{} - \openin 1 \jobname.toc - \ifeof 1 \else - \closein 1 - \input \jobname.toc - \fi - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \endgroup - \lastnegativepageno = \pageno - \pageno = \savepageno -} -\let\shortcontents = \summarycontents - -\ifpdf - \pdfcatalog{/PageMode /UseOutlines}% -\fi - -% These macros generate individual entries in the table of contents. -% The first argument is the chapter or section name. -% The last argument is the page number. -% The arguments in between are the chapter number, section number, ... - -% Chapter-level things, for both the long and short contents. -\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} - -% See comments in \dochapentry re vbox and related settings -\def\shortchapentry#1#2#3{% - \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% -} - -% Typeset the label for a chapter or appendix for the short contents. -% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. -% We could simplify the code here by writing out an \appendixentry -% command in the toc file for appendices, instead of using \chapentry -% for both, but it doesn't seem worth it. -% -\newdimen\shortappendixwidth -% -\def\shortchaplabel#1{% - % Compute width of word "Appendix", may change with language. - \setbox0 = \hbox{\shortcontrm \putwordAppendix}% - \shortappendixwidth = \wd0 - % - % We typeset #1 in a box of constant width, regardless of the text of - % #1, so the chapter titles will come out aligned. - \setbox0 = \hbox{#1}% - \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi - % - % This space should be plenty, since a single number is .5em, and the - % widest letter (M) is 1em, at least in the Computer Modern fonts. - % (This space doesn't include the extra space that gets added after - % the label; that gets put in by \shortchapentry above.) - \advance\dimen0 by 1.1em - \hbox to \dimen0{#1\hfil}% -} - -\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} -\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno\bgroup#2\egroup}} - -% Sections. -\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} -\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} - -% Subsections. -\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} -\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} - -% And subsubsections. -\def\subsubsecentry#1#2#3#4#5#6{% - \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} -\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} - -% This parameter controls the indentation of the various levels. -\newdimen\tocindent \tocindent = 3pc - -% Now for the actual typesetting. In all these, #1 is the text and #2 is the -% page number. -% -% If the toc has to be broken over pages, we want it to be at chapters -% if at all possible; hence the \penalty. -\def\dochapentry#1#2{% - \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip - \begingroup - \chapentryfonts - \tocentry{#1}{\dopageno\bgroup#2\egroup}% - \endgroup - \nobreak\vskip .25\baselineskip plus.1\baselineskip -} - -\def\dosecentry#1#2{\begingroup - \secentryfonts \leftskip=\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -\def\dosubsecentry#1#2{\begingroup - \subsecentryfonts \leftskip=2\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -\def\dosubsubsecentry#1#2{\begingroup - \subsubsecentryfonts \leftskip=3\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -% Final typesetting of a toc entry; we use the same \entry macro as for -% the index entries, but we want to suppress hyphenation here. (We -% can't do that in the \entry macro, since index entries might consist -% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) -\def\tocentry#1#2{\begingroup - \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks - % Do not use \turnoffactive in these arguments. Since the toc is - % typeset in cmr, so characters such as _ would come out wrong; we - % have to do the usual translation tricks. - \entry{#1}{#2}% -\endgroup} - -% Space between chapter (or whatever) number and the title. -\def\labelspace{\hskip1em \relax} - -\def\dopageno#1{{\rm #1}} -\def\doshortpageno#1{{\rm #1}} - -\def\chapentryfonts{\secfonts \rm} -\def\secentryfonts{\textfonts} -\let\subsecentryfonts = \textfonts -\let\subsubsecentryfonts = \textfonts - - -\message{environments,} -% @foo ... @end foo. - -% Since these characters are used in examples, it should be an even number of -% \tt widths. Each \tt character is 1en, so two makes it 1em. -% Furthermore, these definitions must come after we define our fonts. -\newbox\dblarrowbox \newbox\longdblarrowbox -\newbox\pushcharbox \newbox\bullbox -\newbox\equivbox \newbox\errorbox - -%{\tentt -%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} -%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} -%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} -%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} -% Adapted from the manmac format (p.420 of TeXbook) -%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex -% depth .1ex\hfil} -%} - -% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. -\def\point{$\star$} -\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} -\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} -\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} -\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} - -% Adapted from the TeXbook's \boxit. -{\tentt \global\dimen0 = 3em}% Width of the box. -\dimen2 = .55pt % Thickness of rules -% The text. (`r' is open on the right, `e' somewhat less so on the left.) -\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} - -\global\setbox\errorbox=\hbox to \dimen0{\hfil - \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. - \advance\hsize by -2\dimen2 % Rules. - \vbox{ - \hrule height\dimen2 - \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. - \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. - \kern3pt\vrule width\dimen2}% Space to right. - \hrule height\dimen2} - \hfil} - -% The @error{} command. -\def\error{\leavevmode\lower.7ex\copy\errorbox} - -% @tex ... @end tex escapes into raw Tex temporarily. -% One exception: @ is still an escape character, so that @end tex works. -% But \@ or @@ will get a plain tex @ character. - -\def\tex{\begingroup - \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 - \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 - \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie - \catcode `\%=14 - \catcode 43=12 % plus - \catcode`\"=12 - \catcode`\==12 - \catcode`\|=12 - \catcode`\<=12 - \catcode`\>=12 - \escapechar=`\\ - % - \let\b=\ptexb - \let\bullet=\ptexbullet - \let\c=\ptexc - \let\,=\ptexcomma - \let\.=\ptexdot - \let\dots=\ptexdots - \let\equiv=\ptexequiv - \let\!=\ptexexclam - \let\i=\ptexi - \let\{=\ptexlbrace - \let\+=\tabalign - \let\}=\ptexrbrace - \let\*=\ptexstar - \let\t=\ptext - % - \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% - \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% - \def\@{@}% -\let\Etex=\endgroup} - -% Define @lisp ... @endlisp. -% @lisp does a \begingroup so it can rebind things, -% including the definition of @endlisp (which normally is erroneous). - -% Amount to narrow the margins by for @lisp. -\newskip\lispnarrowing \lispnarrowing=0.4in - -% This is the definition that ^^M gets inside @lisp, @example, and other -% such environments. \null is better than a space, since it doesn't -% have any width. -\def\lisppar{\null\endgraf} - -% Make each space character in the input produce a normal interword -% space in the output. Don't allow a line break at this space, as this -% is used only in environments like @example, where each line of input -% should produce a line of output anyway. -% -{\obeyspaces % -\gdef\sepspaces{\obeyspaces\let =\tie}} - -% Define \obeyedspace to be our active space, whatever it is. This is -% for use in \parsearg. -{\sepspaces% -\global\let\obeyedspace= } - -% This space is always present above and below environments. -\newskip\envskipamount \envskipamount = 0pt - -% Make spacing and below environment symmetrical. We use \parskip here -% to help in doing that, since in @example-like environments \parskip -% is reset to zero; thus the \afterenvbreak inserts no space -- but the -% start of the next paragraph will insert \parskip -% -\def\aboveenvbreak{{\advance\envskipamount by \parskip -\endgraf \ifdim\lastskip<\envskipamount -\removelastskip \penalty-50 \vskip\envskipamount \fi}} - -\let\afterenvbreak = \aboveenvbreak - -% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. -\let\nonarrowing=\relax - -% @cartouche ... @end cartouche: draw rectangle w/rounded corners around -% environment contents. -\font\circle=lcircle10 -\newdimen\circthick -\newdimen\cartouter\newdimen\cartinner -\newskip\normbskip\newskip\normpskip\newskip\normlskip -\circthick=\fontdimen8\circle -% -\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth -\def\ctr{{\hskip 6pt\circle\char'010}} -\def\cbl{{\circle\char'012\hskip -6pt}} -\def\cbr{{\hskip 6pt\circle\char'011}} -\def\carttop{\hbox to \cartouter{\hskip\lskip - \ctl\leaders\hrule height\circthick\hfil\ctr - \hskip\rskip}} -\def\cartbot{\hbox to \cartouter{\hskip\lskip - \cbl\leaders\hrule height\circthick\hfil\cbr - \hskip\rskip}} -% -\newskip\lskip\newskip\rskip - -\long\def\cartouche{% -\begingroup - \lskip=\leftskip \rskip=\rightskip - \leftskip=0pt\rightskip=0pt %we want these *outside*. - \cartinner=\hsize \advance\cartinner by-\lskip - \advance\cartinner by-\rskip - \cartouter=\hsize - \advance\cartouter by 18.4pt % allow for 3pt kerns on either -% side, and for 6pt waste from -% each corner char, and rule thickness - \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip - % Flag to tell @lisp, etc., not to narrow margin. - \let\nonarrowing=\comment - \vbox\bgroup - \baselineskip=0pt\parskip=0pt\lineskip=0pt - \carttop - \hbox\bgroup - \hskip\lskip - \vrule\kern3pt - \vbox\bgroup - \hsize=\cartinner - \kern3pt - \begingroup - \baselineskip=\normbskip - \lineskip=\normlskip - \parskip=\normpskip - \vskip -\parskip -\def\Ecartouche{% - \endgroup - \kern3pt - \egroup - \kern3pt\vrule - \hskip\rskip - \egroup - \cartbot - \egroup -\endgroup -}} - - -% This macro is called at the beginning of all the @example variants, -% inside a group. -\def\nonfillstart{% - \aboveenvbreak - \inENV % This group ends at the end of the body - \hfuzz = 12pt % Don't be fussy - \sepspaces % Make spaces be word-separators rather than space tokens. - \singlespace - \let\par = \lisppar % don't ignore blank lines - \obeylines % each line of input is a line of output - \parskip = 0pt - \parindent = 0pt - \emergencystretch = 0pt % don't try to avoid overfull boxes - % @cartouche defines \nonarrowing to inhibit narrowing - % at next level down. - \ifx\nonarrowing\relax - \advance \leftskip by \lispnarrowing - \exdentamount=\lispnarrowing - \let\exdent=\nofillexdent - \let\nonarrowing=\relax - \fi -} - -% Define the \E... control sequence only if we are inside the particular -% environment, so the error checking in \end will work. -% -% To end an @example-like environment, we first end the paragraph (via -% \afterenvbreak's vertical glue), and then the group. That way we keep -% the zero \parskip that the environments set -- \parskip glue will be -% inserted at the beginning of the next paragraph in the document, after -% the environment. -% -\def\nonfillfinish{\afterenvbreak\endgroup} - -% @lisp: indented, narrowed, typewriter font. -\def\lisp{\begingroup - \nonfillstart - \let\Elisp = \nonfillfinish - \tt - \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return -} - -% @example: Same as @lisp. -\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} - -% @small... is usually equivalent to the non-small (@smallbook -% redefines). We must call \example (or whatever) last in the -% definition, since it reads the return following the @example (or -% whatever) command. -% -% This actually allows (for example) @end display inside an -% @smalldisplay. Too bad, but makeinfo will catch the error anyway. -% -\def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display} -\def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp} -\def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format} -\def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp} - -% Real @smallexample and @smalllisp (when @smallbook): use smaller fonts. -% Originally contributed by Pavel@xerox. -\def\smalllispx{\begingroup - \def\Esmalllisp{\nonfillfinish\endgroup}% - \def\Esmallexample{\nonfillfinish\endgroup}% - \smallfonts - \lisp -} - -% @display: same as @lisp except keep current font. -% -\def\display{\begingroup - \nonfillstart - \let\Edisplay = \nonfillfinish - \gobble -} - -% @smalldisplay (when @smallbook): @display plus smaller fonts. -% -\def\smalldisplayx{\begingroup - \def\Esmalldisplay{\nonfillfinish\endgroup}% - \smallfonts \rm - \display -} - -% @format: same as @display except don't narrow margins. -% -\def\format{\begingroup - \let\nonarrowing = t - \nonfillstart - \let\Eformat = \nonfillfinish - \gobble -} - -% @smallformat (when @smallbook): @format plus smaller fonts. -% -\def\smallformatx{\begingroup - \def\Esmallformat{\nonfillfinish\endgroup}% - \smallfonts \rm - \format -} - -% @flushleft (same as @format). -% -\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} - -% @flushright. -% -\def\flushright{\begingroup - \let\nonarrowing = t - \nonfillstart - \let\Eflushright = \nonfillfinish - \advance\leftskip by 0pt plus 1fill - \gobble -} - -% @quotation does normal linebreaking (hence we can't use \nonfillstart) -% and narrows the margins. -% -\def\quotation{% - \begingroup\inENV %This group ends at the end of the @quotation body - {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip - \singlespace - \parindent=0pt - % We have retained a nonzero parskip for the environment, since we're - % doing normal filling. So to avoid extra space below the environment... - \def\Equotation{\parskip = 0pt \nonfillfinish}% - % - % @cartouche defines \nonarrowing to inhibit narrowing at next level down. - \ifx\nonarrowing\relax - \advance\leftskip by \lispnarrowing - \advance\rightskip by \lispnarrowing - \exdentamount = \lispnarrowing - \let\nonarrowing = \relax - \fi -} - - -\message{defuns,} -% @defun etc. - -% Allow user to change definition object font (\df) internally -\def\setdeffont #1 {\csname DEF#1\endcsname} - -\newskip\defbodyindent \defbodyindent=.4in -\newskip\defargsindent \defargsindent=50pt -\newskip\deftypemargin \deftypemargin=12pt -\newskip\deflastargmargin \deflastargmargin=18pt - -\newcount\parencount -% define \functionparens, which makes ( and ) and & do special things. -% \functionparens affects the group it is contained in. -\def\activeparens{% -\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active -\catcode`\[=\active \catcode`\]=\active} - -% Make control sequences which act like normal parenthesis chars. -\let\lparen = ( \let\rparen = ) - -{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) - -% Be sure that we always have a definition for `(', etc. For example, -% if the fn name has parens in it, \boldbrax will not be in effect yet, -% so TeX would otherwise complain about undefined control sequence. -\global\let(=\lparen \global\let)=\rparen -\global\let[=\lbrack \global\let]=\rbrack - -\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } -\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} -% This is used to turn on special parens -% but make & act ordinary (given that it's active). -\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} - -% Definitions of (, ) and & used in args for functions. -% This is the definition of ( outside of all parentheses. -\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested - \global\advance\parencount by 1 -} -% -% This is the definition of ( when already inside a level of parens. -\gdef\opnested{\char`\(\global\advance\parencount by 1 } -% -\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. - % also in that case restore the outer-level definition of (. - \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi - \global\advance \parencount by -1 } -% If we encounter &foo, then turn on ()-hacking afterwards -\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } -% -\gdef\normalparens{\boldbrax\let&=\ampnr} -} % End of definition inside \activeparens -%% These parens (in \boldbrax) actually are a little bolder than the -%% contained text. This is especially needed for [ and ] -\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } -\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } -\let\ampnr = \& -\def\lbrb{{\bf\char`\[}} -\def\rbrb{{\bf\char`\]}} - -% Active &'s sneak into the index arguments, so make sure it's defined. -{ - \catcode`& = 13 - \global\let& = \ampnr -} - -% First, defname, which formats the header line itself. -% #1 should be the function name. -% #2 should be the type of definition, such as "Function". - -\def\defname #1#2{% -% Get the values of \leftskip and \rightskip as they were -% outside the @def... -\dimen2=\leftskip -\advance\dimen2 by -\defbodyindent -\noindent -\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% -\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line -\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations -\parshape 2 0in \dimen0 \defargsindent \dimen1 -% Now output arg 2 ("Function" or some such) -% ending at \deftypemargin from the right margin, -% but stuck inside a box of width 0 so it does not interfere with linebreaking -{% Adjust \hsize to exclude the ambient margins, -% so that \rightline will obey them. -\advance \hsize by -\dimen2 -\rlap{\rightline{{\rm #2}\hskip -1.25pc }}}% -% Make all lines underfull and no complaints: -\tolerance=10000 \hbadness=10000 -\advance\leftskip by -\defbodyindent -\exdentamount=\defbodyindent -{\df #1}\enskip % Generate function name -} - -% Actually process the body of a definition -% #1 should be the terminating control sequence, such as \Edefun. -% #2 should be the "another name" control sequence, such as \defunx. -% #3 should be the control sequence that actually processes the header, -% such as \defunheader. - -\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody -\medbreak % -% Define the end token that this defining construct specifies -% so that it will exit this group. -\def#1{\endgraf\endgroup\medbreak}% -\def#2{\begingroup\obeylines\activeparens\spacesplit#3}% -\parindent=0in -\advance\leftskip by \defbodyindent -\exdentamount=\defbodyindent -\begingroup % -\catcode 61=\active % 61 is `=' -\obeylines\activeparens\spacesplit#3} - -% #1 is the \E... control sequence to end the definition (which we define). -% #2 is the \...x control sequence for consecutive fns (which we define). -% #3 is the control sequence to call to resume processing. -% #4, delimited by the space, is the class name. -% -\def\defmethparsebody#1#2#3#4 {\begingroup\inENV % -\medbreak % -% Define the end token that this defining construct specifies -% so that it will exit this group. -\def#1{\endgraf\endgroup\medbreak}% -\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% -\parindent=0in -\advance\leftskip by \defbodyindent -\exdentamount=\defbodyindent -\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} - -% Used for @deftypemethod and @deftypeivar. -% #1 is the \E... control sequence to end the definition (which we define). -% #2 is the \...x control sequence for consecutive fns (which we define). -% #3 is the control sequence to call to resume processing. -% #4, delimited by a space, is the class name. -% #5 is the method's return type. -% -\def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV - \medbreak - \def#1{\endgraf\endgroup\medbreak}% - \def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}% - \parindent=0in - \advance\leftskip by \defbodyindent - \exdentamount=\defbodyindent - \begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}} - -% Used for @deftypeop. The change from \deftypemethparsebody is an -% extra argument at the beginning which is the `category', instead of it -% being the hardwired string `Method' or `Instance Variable'. We have -% to account for this both in the \...x definition and in parsing the -% input at hand. Thus also need a control sequence (passed as #5) for -% the \E... definition to assign the category name to. -% -\def\deftypeopparsebody#1#2#3#4#5 #6 {\begingroup\inENV - \medbreak - \def#1{\endgraf\endgroup\medbreak}% - \def#2##1 ##2 ##3 {% - \def#4{##1}% - \begingroup\obeylines\activeparens\spacesplit{#3{##2}{##3}}}% - \parindent=0in - \advance\leftskip by \defbodyindent - \exdentamount=\defbodyindent - \begingroup\obeylines\activeparens\spacesplit{#3{#5}{#6}}} - -\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % -\medbreak % -% Define the end token that this defining construct specifies -% so that it will exit this group. -\def#1{\endgraf\endgroup\medbreak}% -\def#2##1 ##2 {\def#4{##1}% -\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% -\parindent=0in -\advance\leftskip by \defbodyindent -\exdentamount=\defbodyindent -\begingroup\obeylines\activeparens\spacesplit{#3{#5}}} - -% These parsing functions are similar to the preceding ones -% except that they do not make parens into active characters. -% These are used for "variables" since they have no arguments. - -\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody -\medbreak % -% Define the end token that this defining construct specifies -% so that it will exit this group. -\def#1{\endgraf\endgroup\medbreak}% -\def#2{\begingroup\obeylines\spacesplit#3}% -\parindent=0in -\advance\leftskip by \defbodyindent -\exdentamount=\defbodyindent -\begingroup % -\catcode 61=\active % -\obeylines\spacesplit#3} - -% This is used for \def{tp,vr}parsebody. It could probably be used for -% some of the others, too, with some judicious conditionals. -% -\def\parsebodycommon#1#2#3{% - \begingroup\inENV % - \medbreak % - % Define the end token that this defining construct specifies - % so that it will exit this group. - \def#1{\endgraf\endgroup\medbreak}% - \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% - \parindent=0in - \advance\leftskip by \defbodyindent - \exdentamount=\defbodyindent - \begingroup\obeylines -} - -\def\defvrparsebody#1#2#3#4 {% - \parsebodycommon{#1}{#2}{#3}% - \spacesplit{#3{#4}}% -} - -% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the -% type is just `struct', because we lose the braces in `{struct -% termios}' when \spacesplit reads its undelimited argument. Sigh. -% \let\deftpparsebody=\defvrparsebody -% -% So, to get around this, we put \empty in with the type name. That -% way, TeX won't find exactly `{...}' as an undelimited argument, and -% won't strip off the braces. -% -\def\deftpparsebody #1#2#3#4 {% - \parsebodycommon{#1}{#2}{#3}% - \spacesplit{\parsetpheaderline{#3{#4}}}\empty -} - -% Fine, but then we have to eventually remove the \empty *and* the -% braces (if any). That's what this does. -% -\def\removeemptybraces\empty#1\relax{#1} - -% After \spacesplit has done its work, this is called -- #1 is the final -% thing to call, #2 the type name (which starts with \empty), and #3 -% (which might be empty) the arguments. -% -\def\parsetpheaderline#1#2#3{% - #1{\removeemptybraces#2\relax}{#3}% -}% - -\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % -\medbreak % -% Define the end token that this defining construct specifies -% so that it will exit this group. -\def#1{\endgraf\endgroup\medbreak}% -\def#2##1 ##2 {\def#4{##1}% -\begingroup\obeylines\spacesplit{#3{##2}}}% -\parindent=0in -\advance\leftskip by \defbodyindent -\exdentamount=\defbodyindent -\begingroup\obeylines\spacesplit{#3{#5}}} - -% Split up #2 at the first space token. -% call #1 with two arguments: -% the first is all of #2 before the space token, -% the second is all of #2 after that space token. -% If #2 contains no space token, all of it is passed as the first arg -% and the second is passed as empty. - -{\obeylines -\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% -\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% -\ifx\relax #3% -#1{#2}{}\else #1{#2}{#3#4}\fi}} - -% So much for the things common to all kinds of definitions. - -% Define @defun. - -% First, define the processing that is wanted for arguments of \defun -% Use this to expand the args and terminate the paragraph they make up - -\def\defunargs#1{\functionparens \sl -% Expand, preventing hyphenation at `-' chars. -% Note that groups don't affect changes in \hyphenchar. -% Set the font temporarily and use \font in case \setfont made \tensl a macro. -{\tensl\hyphenchar\font=0}% -#1% -{\tensl\hyphenchar\font=45}% -\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% -\interlinepenalty=10000 -\advance\rightskip by 0pt plus 1fil -\endgraf\nobreak\vskip -\parskip\nobreak -} - -\def\deftypefunargs #1{% -% Expand, preventing hyphenation at `-' chars. -% Note that groups don't affect changes in \hyphenchar. -% Use \boldbraxnoamp, not \functionparens, so that & is not special. -\boldbraxnoamp -\tclose{#1}% avoid \code because of side effects on active chars -\interlinepenalty=10000 -\advance\rightskip by 0pt plus 1fil -\endgraf\nobreak\vskip -\parskip\nobreak -} - -% Do complete processing of one @defun or @defunx line already parsed. - -% @deffn Command forward-char nchars - -\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} - -\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% -\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % -\catcode 61=\other % Turn off change made in \defparsebody -} - -% @defun == @deffn Function - -\def\defun{\defparsebody\Edefun\defunx\defunheader} - -\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDeffunc}% -\defunargs {#2}\endgroup % -\catcode 61=\other % Turn off change made in \defparsebody -} - -% @deftypefun int foobar (int @var{foo}, float @var{bar}) - -\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} - -% #1 is the data type. #2 is the name and args. -\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} -% #1 is the data type, #2 the name, #3 the args. -\def\deftypefunheaderx #1#2 #3\relax{% -\doind {fn}{\code{#2}}% Make entry in function index -\begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypefun}% -\deftypefunargs {#3}\endgroup % -\catcode 61=\other % Turn off change made in \defparsebody -} - -% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) - -\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} - -% \defheaderxcond#1\relax$$$ -% puts #1 in @code, followed by a space, but does nothing if #1 is null. -\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} - -% #1 is the classification. #2 is the data type. #3 is the name and args. -\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} -% #1 is the classification, #2 the data type, #3 the name, #4 the args. -\def\deftypefnheaderx #1#2#3 #4\relax{% -\doind {fn}{\code{#3}}% Make entry in function index -\begingroup -\normalparens % notably, turn off `&' magic, which prevents -% at least some C++ text from working -\defname {\defheaderxcond#2\relax$$$#3}{#1}% -\deftypefunargs {#4}\endgroup % -\catcode 61=\other % Turn off change made in \defparsebody -} - -% @defmac == @deffn Macro - -\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} - -\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDefmac}% -\defunargs {#2}\endgroup % -\catcode 61=\other % Turn off change made in \defparsebody -} - -% @defspec == @deffn Special Form - -\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} - -\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDefspec}% -\defunargs {#2}\endgroup % -\catcode 61=\other % Turn off change made in \defparsebody -} - -% @defop CATEGORY CLASS OPERATION ARG... -% -\def\defop #1 {\def\defoptype{#1}% -\defopparsebody\Edefop\defopx\defopheader\defoptype} -% -\def\defopheader#1#2#3{% -\dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index -\begingroup\defname {#2}{\defoptype\ \putwordon\ #1}% -\defunargs {#3}\endgroup % -} - -% @deftypeop CATEGORY CLASS TYPE OPERATION ARG... -% -\def\deftypeop #1 {\def\deftypeopcategory{#1}% - \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader - \deftypeopcategory} -% -% #1 is the class name, #2 the data type, #3 the operation name, #4 the args. -\def\deftypeopheader#1#2#3#4{% - \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{\defheaderxcond#2\relax$$$#3} - {\deftypeopcategory\ \putwordon\ \code{#1}}% - \deftypefunargs{#4}% - \endgroup -} - -% @deftypemethod CLASS TYPE METHOD ARG... -% -\def\deftypemethod{% - \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} -% -% #1 is the class name, #2 the data type, #3 the method name, #4 the args. -\def\deftypemethodheader#1#2#3#4{% - \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}% - \deftypefunargs{#4}% - \endgroup -} - -% @deftypeivar CLASS TYPE VARNAME -% -\def\deftypeivar{% - \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} -% -% #1 is the class name, #2 the data type, #3 the variable name. -\def\deftypeivarheader#1#2#3{% - \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index - \begingroup - \defname{#3}{\putwordInstanceVariableof\ \code{#1}}% - \defvarargs{#3}% - \endgroup -} - -% @defmethod == @defop Method -% -\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} -% -% #1 is the class name, #2 the method name, #3 the args. -\def\defmethodheader#1#2#3{% - \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{#2}{\putwordMethodon\ \code{#1}}% - \defunargs{#3}% - \endgroup -} - -% @defcv {Class Option} foo-class foo-flag - -\def\defcv #1 {\def\defcvtype{#1}% -\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} - -\def\defcvarheader #1#2#3{% -\dosubind {vr}{\code{#2}}{\putwordof\ #1}% Make entry in var index -\begingroup\defname {#2}{\defcvtype\ \putwordof\ #1}% -\defvarargs {#3}\endgroup % -} - -% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME -% -\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} -% -\def\defivarheader#1#2#3{% - \dosubind {vr}{\code{#2}}{\putwordof\ #1}% entry in var index - \begingroup - \defname{#2}{\putwordInstanceVariableof\ #1}% - \defvarargs{#3}% - \endgroup -} - -% @defvar -% First, define the processing that is wanted for arguments of @defvar. -% This is actually simple: just print them in roman. -% This must expand the args and terminate the paragraph they make up -\def\defvarargs #1{\normalparens #1% -\interlinepenalty=10000 -\endgraf\nobreak\vskip -\parskip\nobreak} - -% @defvr Counter foo-count - -\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} - -\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% -\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} - -% @defvar == @defvr Variable - -\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} - -\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index -\begingroup\defname {#1}{\putwordDefvar}% -\defvarargs {#2}\endgroup % -} - -% @defopt == @defvr {User Option} - -\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} - -\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index -\begingroup\defname {#1}{\putwordDefopt}% -\defvarargs {#2}\endgroup % -} - -% @deftypevar int foobar - -\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} - -% #1 is the data type. #2 is the name, perhaps followed by text that -% is actually part of the data type, which should not be put into the index. -\def\deftypevarheader #1#2{% -\dovarind#2 \relax% Make entry in variables index -\begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypevar}% -\interlinepenalty=10000 -\endgraf\nobreak\vskip -\parskip\nobreak -\endgroup} -\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} - -% @deftypevr {Global Flag} int enable - -\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} - -\def\deftypevrheader #1#2#3{\dovarind#3 \relax% -\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} -\interlinepenalty=10000 -\endgraf\nobreak\vskip -\parskip\nobreak -\endgroup} - -% Now define @deftp -% Args are printed in bold, a slight difference from @defvar. - -\def\deftpargs #1{\bf \defvarargs{#1}} - -% @deftp Class window height width ... - -\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} - -\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% -\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} - -% These definitions are used if you use @defunx (etc.) -% anywhere other than immediately after a @defun or @defunx. -% -\def\defcvx#1 {\errmessage{@defcvx in invalid context}} -\def\deffnx#1 {\errmessage{@deffnx in invalid context}} -\def\defivarx#1 {\errmessage{@defivarx in invalid context}} -\def\defmacx#1 {\errmessage{@defmacx in invalid context}} -\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} -\def\defoptx #1 {\errmessage{@defoptx in invalid context}} -\def\defopx#1 {\errmessage{@defopx in invalid context}} -\def\defspecx#1 {\errmessage{@defspecx in invalid context}} -\def\deftpx#1 {\errmessage{@deftpx in invalid context}} -\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} -\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} -\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} -\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} -\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} -\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} -\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} -\def\defunx#1 {\errmessage{@defunx in invalid context}} -\def\defvarx#1 {\errmessage{@defvarx in invalid context}} -\def\defvrx#1 {\errmessage{@defvrx in invalid context}} - - -\message{macros,} -% @macro. - -% To do this right we need a feature of e-TeX, \scantokens, -% which we arrange to emulate with a temporary file in ordinary TeX. -\ifx\eTeXversion\undefined - \newwrite\macscribble - \def\scanmacro#1{% - \begingroup \newlinechar`\^^M - % Undo catcode changes of \startcontents and \doprintindex - \catcode`\@=0 \catcode`\\=12 \escapechar=`\@ - % Append \endinput to make sure that TeX does not see the ending newline. - \toks0={#1\endinput}% - \immediate\openout\macscribble=\jobname.tmp - \immediate\write\macscribble{\the\toks0}% - \immediate\closeout\macscribble - \let\xeatspaces\eatspaces - \input \jobname.tmp - \endgroup -} -\else -\def\scanmacro#1{% -\begingroup \newlinechar`\^^M -% Undo catcode changes of \startcontents and \doprintindex -\catcode`\@=0 \catcode`\\=12 \escapechar=`\@ -\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} -\fi - -\newcount\paramno % Count of parameters -\newtoks\macname % Macro name -\newif\ifrecursive % Is it recursive? -\def\macrolist{} % List of all defined macros in the form - % \do\macro1\do\macro2... - -% Utility routines. -% Thisdoes \let #1 = #2, except with \csnames. -\def\cslet#1#2{% -\expandafter\expandafter -\expandafter\let -\expandafter\expandafter -\csname#1\endcsname -\csname#2\endcsname} - -% Trim leading and trailing spaces off a string. -% Concepts from aro-bend problem 15 (see CTAN). -{\catcode`\@=11 -\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} -\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} -\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} -\def\unbrace#1{#1} -\unbrace{\gdef\trim@@@ #1 } #2@{#1} -} - -% Trim a single trailing ^^M off a string. -{\catcode`\^^M=12\catcode`\Q=3% -\gdef\eatcr #1{\eatcra #1Q^^MQ}% -\gdef\eatcra#1^^MQ{\eatcrb#1Q}% -\gdef\eatcrb#1Q#2Q{#1}% -} - -% Macro bodies are absorbed as an argument in a context where -% all characters are catcode 10, 11 or 12, except \ which is active -% (as in normal texinfo). It is necessary to change the definition of \. - -% It's necessary to have hard CRs when the macro is executed. This is -% done by making ^^M (\endlinechar) catcode 12 when reading the macro -% body, and then making it the \newlinechar in \scanmacro. - -\def\macrobodyctxt{% - \catcode`\~=12 - \catcode`\^=12 - \catcode`\_=12 - \catcode`\|=12 - \catcode`\<=12 - \catcode`\>=12 - \catcode`\+=12 - \catcode`\{=12 - \catcode`\}=12 - \catcode`\@=12 - \catcode`\^^M=12 - \usembodybackslash} - -\def\macroargctxt{% - \catcode`\~=12 - \catcode`\^=12 - \catcode`\_=12 - \catcode`\|=12 - \catcode`\<=12 - \catcode`\>=12 - \catcode`\+=12 - \catcode`\@=12 - \catcode`\\=12} - -% \mbodybackslash is the definition of \ in @macro bodies. -% It maps \foo\ => \csname macarg.foo\endcsname => #N -% where N is the macro parameter number. -% We define \csname macarg.\endcsname to be \realbackslash, so -% \\ in macro replacement text gets you a backslash. - -{\catcode`@=0 @catcode`@\=@active - @gdef@usembodybackslash{@let\=@mbodybackslash} - @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} -} -\expandafter\def\csname macarg.\endcsname{\realbackslash} - -\def\macro{\recursivefalse\parsearg\macroxxx} -\def\rmacro{\recursivetrue\parsearg\macroxxx} - -\def\macroxxx#1{% - \getargs{#1}% now \macname is the macname and \argl the arglist - \ifx\argl\empty % no arguments - \paramno=0% - \else - \expandafter\parsemargdef \argl;% - \fi - \if1\csname ismacro.\the\macname\endcsname - \message{Warning: redefining \the\macname}% - \else - \expandafter\ifx\csname \the\macname\endcsname \relax - \else \errmessage{The name \the\macname\space is reserved}\fi - \global\cslet{macsave.\the\macname}{\the\macname}% - \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% - % Add the macroname to \macrolist - \toks0 = \expandafter{\macrolist\do}% - \xdef\macrolist{\the\toks0 - \expandafter\noexpand\csname\the\macname\endcsname}% - \fi - \begingroup \macrobodyctxt - \ifrecursive \expandafter\parsermacbody - \else \expandafter\parsemacbody - \fi} - -\def\unmacro{\parsearg\unmacroxxx} -\def\unmacroxxx#1{% - \if1\csname ismacro.#1\endcsname - \global\cslet{#1}{macsave.#1}% - \global\expandafter\let \csname ismacro.#1\endcsname=0% - % Remove the macro name from \macrolist - \begingroup - \edef\tempa{\expandafter\noexpand\csname#1\endcsname}% - \def\do##1{% - \def\tempb{##1}% - \ifx\tempa\tempb - % remove this - \else - \toks0 = \expandafter{\newmacrolist\do}% - \edef\newmacrolist{\the\toks0\expandafter\noexpand\tempa}% - \fi}% - \def\newmacrolist{}% - % Execute macro list to define \newmacrolist - \macrolist - \global\let\macrolist\newmacrolist - \endgroup - \else - \errmessage{Macro #1 not defined}% - \fi -} - -% This makes use of the obscure feature that if the last token of a -% is #, then the preceding argument is delimited by -% an opening brace, and that opening brace is not consumed. -\def\getargs#1{\getargsxxx#1{}} -\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} -\def\getmacname #1 #2\relax{\macname={#1}} -\def\getmacargs#1{\def\argl{#1}} - -% Parse the optional {params} list. Set up \paramno and \paramlist -% so \defmacro knows what to do. Define \macarg.blah for each blah -% in the params list, to be ##N where N is the position in that list. -% That gets used by \mbodybackslash (above). - -% We need to get `macro parameter char #' into several definitions. -% The technique used is stolen from LaTeX: let \hash be something -% unexpandable, insert that wherever you need a #, and then redefine -% it to # just before using the token list produced. -% -% The same technique is used to protect \eatspaces till just before -% the macro is used. - -\def\parsemargdef#1;{\paramno=0\def\paramlist{}% - \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} -\def\parsemargdefxxx#1,{% - \if#1;\let\next=\relax - \else \let\next=\parsemargdefxxx - \advance\paramno by 1% - \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname - {\xeatspaces{\hash\the\paramno}}% - \edef\paramlist{\paramlist\hash\the\paramno,}% - \fi\next} - -% These two commands read recursive and nonrecursive macro bodies. -% (They're different since rec and nonrec macros end differently.) - -\long\def\parsemacbody#1@end macro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% -\long\def\parsermacbody#1@end rmacro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% - -% This defines the macro itself. There are six cases: recursive and -% nonrecursive macros of zero, one, and many arguments. -% Much magic with \expandafter here. -% \xdef is used so that macro definitions will survive the file -% they're defined in; @include reads the file inside a group. -\def\defmacro{% - \let\hash=##% convert placeholders to macro parameter chars - \ifrecursive - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\scanmacro{\temp}}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup\noexpand\scanmacro{\temp}}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{\egroup\noexpand\scanmacro{\temp}}% - \fi - \else - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \expandafter\noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \fi - \fi} - -\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} - -% \braceorline decides whether the next nonwhitespace character is a -% {. If so it reads up to the closing }, if not, it reads the whole -% line. Whatever was read is then fed to the next control sequence -% as an argument (by \parsebrace or \parsearg) -\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} -\def\braceorlinexxx{% - \ifx\nchar\bgroup\else - \expandafter\parsearg - \fi \next} - -% We mant to disable all macros during \shipout so that they are not -% expanded by \write. -\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% - \edef\next{\macrolist}\expandafter\endgroup\next} - - -% @alias. -% We need some trickery to remove the optional spaces around the equal -% sign. Just make them active and then expand them all to nothing. -\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} -\def\aliasxxx #1{\aliasyyy#1\relax} -\def\aliasyyy #1=#2\relax{\ignoreactivespaces -\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% - \expandafter\noexpand\csname#2\endcsname}% -\expandafter\endgroup\next} - - -\message{cross references,} -% @xref etc. - -\newwrite\auxfile - -\newif\ifhavexrefs % True if xref values are known. -\newif\ifwarnedxrefs % True if we warned once that they aren't known. - -% @inforef is relatively simple. -\def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, - node \samp{\ignorespaces#1{}}} - -% @node's job is to define \lastnode. -\def\node{\ENVcheck\parsearg\nodezzz} -\def\nodezzz#1{\nodexxx [#1,]} -\def\nodexxx[#1,#2]{\gdef\lastnode{#1}} -\let\nwnode=\node -\let\lastnode=\relax - -% The sectioning commands (@chapter, etc.) call these. -\def\donoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}% - {Ysectionnumberandtype}% - \global\let\lastnode=\relax - \fi -} -\def\unnumbnoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% - \global\let\lastnode=\relax - \fi -} -\def\appendixnoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}% - {Yappendixletterandtype}% - \global\let\lastnode=\relax - \fi -} - - -% @anchor{NAME} -- define xref target at arbitrary point. -% -\newcount\savesfregister -\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} -\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} -\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} - -% \setref{NAME}{SNT} defines a cross-reference point NAME, namely -% NAME-title, NAME-pg, and NAME-SNT. Called from \foonoderef. We have -% to set \indexdummies so commands such as @code in a section title -% aren't expanded. It would be nicer not to expand the titles in the -% first place, but there's so many layers that that is hard to do. -% -\def\setref#1#2{{% - \indexdummies - \pdfmkdest{#1}% - \dosetq{#1-title}{Ytitle}% - \dosetq{#1-pg}{Ypagenumber}% - \dosetq{#1-snt}{#2}% -}} - -% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is -% the node name, #2 the name of the Info cross-reference, #3 the printed -% node name, #4 the name of the Info file, #5 the name of the printed -% manual. All but the node name can be omitted. -% -\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} -\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} -\def\ref#1{\xrefX[#1,,,,,,,]} -\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup - \unsepspaces - \def\printedmanual{\ignorespaces #5}% - \def\printednodename{\ignorespaces #3}% - \setbox1=\hbox{\printedmanual}% - \setbox0=\hbox{\printednodename}% - \ifdim \wd0 = 0pt - % No printed node name was explicitly given. - \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax - % Use the node name inside the square brackets. - \def\printednodename{\ignorespaces #1}% - \else - % Use the actual chapter/section title appear inside - % the square brackets. Use the real section title if we have it. - \ifdim \wd1 > 0pt - % It is in another manual, so we don't have it. - \def\printednodename{\ignorespaces #1}% - \else - \ifhavexrefs - % We know the real title if we have the xref values. - \def\printednodename{\refx{#1-title}{}}% - \else - % Otherwise just copy the Info node name. - \def\printednodename{\ignorespaces #1}% - \fi% - \fi - \fi - \fi - % - % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not - % insert empty discretionaries after hyphens, which means that it will - % not find a line break at a hyphen in a node names. Since some manuals - % are best written with fairly long node names, containing hyphens, this - % is a loss. Therefore, we give the text of the node name again, so it - % is as if TeX is seeing it for the first time. - \ifpdf - \leavevmode - \getfilename{#4}% - \ifnum\filenamelength>0 - \startlink attr{/Border [0 0 0]}% - goto file{\the\filename.pdf} name{#1@}% - \else - \startlink attr{/Border [0 0 0]}% - goto name{#1@}% - \fi - \linkcolor - \fi - % - \ifdim \wd1 > 0pt - \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% - \else - % _ (for example) has to be the character _ for the purposes of the - % control sequence corresponding to the node, but it has to expand - % into the usual \leavevmode...\vrule stuff for purposes of - % printing. So we \turnoffactive for the \refx-snt, back on for the - % printing, back off for the \refx-pg. - {\normalturnoffactive - % Only output a following space if the -snt ref is nonempty; for - % @unnumbered and @anchor, it won't be. - \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% - \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi - }% - % [mynode], - [\printednodename],\space - % page 3 - \turnoffactive \putwordpage\tie\refx{#1-pg}{}% - \fi - \endlink -\endgroup} - -% \dosetq is the interface for calls from other macros - -% Use \normalturnoffactive so that punctuation chars such as underscore -% and backslash work in node names. (\turnoffactive doesn't do \.) -\def\dosetq#1#2{% - {\let\folio=0% - \normalturnoffactive - \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% - \iflinks - \next - \fi - }% -} - -% \internalsetq {foo}{page} expands into -% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} -% When the aux file is read, ' is the escape character - -\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} - -% Things to be expanded by \internalsetq - -\def\Ypagenumber{\folio} - -\def\Ytitle{\thissection} - -\def\Ynothing{} - -\def\Ysectionnumberandtype{% -\ifnum\secno=0 \putwordChapter\xreftie\the\chapno % -\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % -\else \ifnum \subsubsecno=0 % -\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % -\else % -\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % -\fi \fi \fi } - -\def\Yappendixletterandtype{% -\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% -\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % -\else \ifnum \subsubsecno=0 % -\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % -\else % -\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % -\fi \fi \fi } - -\gdef\xreftie{'tie} - -% Use TeX 3.0's \inputlineno to get the line number, for better error -% messages, but if we're using an old version of TeX, don't do anything. -% -\ifx\inputlineno\thisisundefined - \let\linenumber = \empty % Non-3.0. -\else - \def\linenumber{\the\inputlineno:\space} -\fi - -% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. -% If its value is nonempty, SUFFIX is output afterward. - -\def\refx#1#2{% - \expandafter\ifx\csname X#1\endcsname\relax - % If not defined, say something at least. - \angleleft un\-de\-fined\angleright - \iflinks - \ifhavexrefs - \message{\linenumber Undefined cross reference `#1'.}% - \else - \ifwarnedxrefs\else - \global\warnedxrefstrue - \message{Cross reference values unknown; you must run TeX again.}% - \fi - \fi - \fi - \else - % It's defined, so just use it. - \csname X#1\endcsname - \fi - #2% Output the suffix in any case. -} - -% This is the macro invoked by entries in the aux file. -% -\def\xrdef#1{\begingroup - % Reenable \ as an escape while reading the second argument. - \catcode`\\ = 0 - \afterassignment\endgroup - \expandafter\gdef\csname X#1\endcsname -} - -% Read the last existing aux file, if any. No error if none exists. -\def\readauxfile{\begingroup - \catcode`\^^@=\other - \catcode`\^^A=\other - \catcode`\^^B=\other - \catcode`\^^C=\other - \catcode`\^^D=\other - \catcode`\^^E=\other - \catcode`\^^F=\other - \catcode`\^^G=\other - \catcode`\^^H=\other - \catcode`\^^K=\other - \catcode`\^^L=\other - \catcode`\^^N=\other - \catcode`\^^P=\other - \catcode`\^^Q=\other - \catcode`\^^R=\other - \catcode`\^^S=\other - \catcode`\^^T=\other - \catcode`\^^U=\other - \catcode`\^^V=\other - \catcode`\^^W=\other - \catcode`\^^X=\other - \catcode`\^^Z=\other - \catcode`\^^[=\other - \catcode`\^^\=\other - \catcode`\^^]=\other - \catcode`\^^^=\other - \catcode`\^^_=\other - \catcode`\@=\other - \catcode`\^=\other - % It was suggested to define this as 7, which would allow ^^e4 etc. - % in xref tags, i.e., node names. But since ^^e4 notation isn't - % supported in the main text, it doesn't seem desirable. Furthermore, - % that is not enough: for node names that actually contain a ^ - % character, we would end up writing a line like this: 'xrdef {'hat - % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first - % argument, and \hat is not an expandable control sequence. It could - % all be worked out, but why? Either we support ^^ or we don't. - % - % The other change necessary for this was to define \auxhat: - % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter - % and then to call \auxhat in \setq. - % - \catcode`\~=\other - \catcode`\[=\other - \catcode`\]=\other - \catcode`\"=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\$=\other - \catcode`\#=\other - \catcode`\&=\other - \catcode`+=\other % avoid \+ for paranoia even though we've turned it off - % Make the characters 128-255 be printing characters - {% - \count 1=128 - \def\loop{% - \catcode\count 1=\other - \advance\count 1 by 1 - \ifnum \count 1<256 \loop \fi - }% - }% - % The aux file uses ' as the escape (for now). - % Turn off \ as an escape so we do not lose on - % entries which were dumped with control sequences in their names. - % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ - % Reference to such entries still does not work the way one would wish, - % but at least they do not bomb out when the aux file is read in. - \catcode`\{=1 - \catcode`\}=2 - \catcode`\%=\other - \catcode`\'=0 - \catcode`\\=\other - % - \openin 1 \jobname.aux - \ifeof 1 \else - \closein 1 - \input \jobname.aux - \global\havexrefstrue - \global\warnedobstrue - \fi - % Open the new aux file. TeX will close it automatically at exit. - \openout\auxfile=\jobname.aux -\endgroup} - - -% Footnotes. - -\newcount \footnoteno - -% The trailing space in the following definition for supereject is -% vital for proper filling; pages come out unaligned when you do a -% pagealignmacro call if that space before the closing brace is -% removed. (Generally, numeric constants should always be followed by a -% space to prevent strange expansion errors.) -\def\supereject{\par\penalty -20000\footnoteno =0 } - -% @footnotestyle is meaningful for info output only. -\let\footnotestyle=\comment - -\let\ptexfootnote=\footnote - -{\catcode `\@=11 -% -% Auto-number footnotes. Otherwise like plain. -\gdef\footnote{% - \global\advance\footnoteno by \@ne - \edef\thisfootno{$^{\the\footnoteno}$}% - % - % In case the footnote comes at the end of a sentence, preserve the - % extra spacing after we do the footnote number. - \let\@sf\empty - \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi - % - % Remove inadvertent blank space before typesetting the footnote number. - \unskip - \thisfootno\@sf - \footnotezzz -}% - -% Don't bother with the trickery in plain.tex to not require the -% footnote text as a parameter. Our footnotes don't need to be so general. -% -% Oh yes, they do; otherwise, @ifset and anything else that uses -% \parseargline fail inside footnotes because the tokens are fixed when -% the footnote is read. --karl, 16nov96. -% -\long\gdef\footnotezzz{\insert\footins\bgroup - % We want to typeset this text as a normal paragraph, even if the - % footnote reference occurs in (for example) a display environment. - % So reset some parameters. - \interlinepenalty\interfootnotelinepenalty - \splittopskip\ht\strutbox % top baseline for broken footnotes - \splitmaxdepth\dp\strutbox - \floatingpenalty\@MM - \leftskip\z@skip - \rightskip\z@skip - \spaceskip\z@skip - \xspaceskip\z@skip - \parindent\defaultparindent - % - \smallfonts \rm - % - % Hang the footnote text off the number. - \hang - \textindent{\thisfootno}% - % - % Don't crash into the line above the footnote text. Since this - % expands into a box, it must come within the paragraph, lest it - % provide a place where TeX can split the footnote. - \footstrut - \futurelet\next\fo@t -} -\def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t - \else\let\next\f@t\fi \next} -\def\f@@t{\bgroup\aftergroup\@foot\let\next} -\def\f@t#1{#1\@foot} -\def\@foot{\strut\par\egroup} - -}%end \catcode `\@=11 - -% Set the baselineskip to #1, and the lineskip and strut size -% correspondingly. There is no deep meaning behind these magic numbers -% used as factors; they just match (closely enough) what Knuth defined. -% -\def\lineskipfactor{.08333} -\def\strutheightpercent{.70833} -\def\strutdepthpercent {.29167} -% -\def\setleading#1{% - \normalbaselineskip = #1\relax - \normallineskip = \lineskipfactor\normalbaselineskip - \normalbaselines - \setbox\strutbox =\hbox{% - \vrule width0pt height\strutheightpercent\baselineskip - depth \strutdepthpercent \baselineskip - }% -} - -% @| inserts a changebar to the left of the current line. It should -% surround any changed text. This approach does *not* work if the -% change spans more than two lines of output. To handle that, we would -% have adopt a much more difficult approach (putting marks into the main -% vertical list for the beginning and end of each change). -% -\def\|{% - % \vadjust can only be used in horizontal mode. - \leavevmode - % - % Append this vertical mode material after the current line in the output. - \vadjust{% - % We want to insert a rule with the height and depth of the current - % leading; that is exactly what \strutbox is supposed to record. - \vskip-\baselineskip - % - % \vadjust-items are inserted at the left edge of the type. So - % the \llap here moves out into the left-hand margin. - \llap{% - % - % For a thicker or thinner bar, change the `1pt'. - \vrule height\baselineskip width1pt - % - % This is the space between the bar and the text. - \hskip 12pt - }% - }% -} - -% For a final copy, take out the rectangles -% that mark overfull boxes (in case you have decided -% that the text looks ok even though it passes the margin). -% -\def\finalout{\overfullrule=0pt} - -% @image. We use the macros from epsf.tex to support this. -% If epsf.tex is not installed and @image is used, we complain. -% -% Check for and read epsf.tex up front. If we read it only at @image -% time, we might be inside a group, and then its definitions would get -% undone and the next image would fail. -\openin 1 = epsf.tex -\ifeof 1 \else - \closein 1 - % Do not bother showing banner with post-v2.7 epsf.tex (available in - % doc/epsf.tex until it shows up on ctan). - \def\epsfannounce{\toks0 = }% - \input epsf.tex -\fi -% -% We will only complain once about lack of epsf.tex. -\newif\ifwarnednoepsf -\newhelp\noepsfhelp{epsf.tex must be installed for images to - work. It is also included in the Texinfo distribution, or you can get - it from ftp://tug.org/tex/epsf.tex.} -% -\def\image#1{% - \ifx\epsfbox\undefined - \ifwarnednoepsf \else - \errhelp = \noepsfhelp - \errmessage{epsf.tex not found, images will be ignored}% - \global\warnednoepsftrue - \fi - \else - \imagexxx #1,,,\finish - \fi -} -% -% Arguments to @image: -% #1 is (mandatory) image filename; we tack on .eps extension. -% #2 is (optional) width, #3 is (optional) height. -% #4 is just the usual extra ignored arg for parsing this stuff. -\def\imagexxx#1,#2,#3,#4\finish{% - \ifpdf - \centerline{\dopdfimage{#1}{#2}{#3}}% - \else - % \epsfbox itself resets \epsf?size at each figure. - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi - \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi - \begingroup - \catcode`\^^M = 5 % in case we're inside an example - % If the image is by itself, center it. - \ifvmode - \nobreak\bigskip - % Usually we'll have text after the image which will insert - % \parskip glue, so insert it here too to equalize the space - % above and below. - \nobreak\vskip\parskip - \nobreak - \centerline{\epsfbox{#1.eps}}% - \bigbreak - \else - % In the middle of a paragraph, no extra space. - \epsfbox{#1.eps}% - \fi - \endgroup - \fi -} - - -\message{localization,} -% and i18n. - -% @documentlanguage is usually given very early, just after -% @setfilename. If done too late, it may not override everything -% properly. Single argument is the language abbreviation. -% It would be nice if we could set up a hyphenation file here. -% -\def\documentlanguage{\parsearg\dodocumentlanguage} -\def\dodocumentlanguage#1{% - \tex % read txi-??.tex file in plain TeX. - % Read the file if it exists. - \openin 1 txi-#1.tex - \ifeof1 - \errhelp = \nolanghelp - \errmessage{Cannot read language file txi-#1.tex}% - \let\temp = \relax - \else - \def\temp{\input txi-#1.tex }% - \fi - \temp - \endgroup -} -\newhelp\nolanghelp{The given language definition file cannot be found or -is empty. Maybe you need to install it? In the current directory -should work if nowhere else does.} - - -% @documentencoding should change something in TeX eventually, most -% likely, but for now just recognize it. -\let\documentencoding = \comment - - -% Page size parameters. -% -\newdimen\defaultparindent \defaultparindent = 15pt - -\chapheadingskip = 15pt plus 4pt minus 2pt -\secheadingskip = 12pt plus 3pt minus 2pt -\subsecheadingskip = 9pt plus 2pt minus 2pt - -% Prevent underfull vbox error messages. -\vbadness = 10000 - -% Don't be so finicky about underfull hboxes, either. -\hbadness = 2000 - -% Following George Bush, just get rid of widows and orphans. -\widowpenalty=10000 -\clubpenalty=10000 - -% Use TeX 3.0's \emergencystretch to help line breaking, but if we're -% using an old version of TeX, don't do anything. We want the amount of -% stretch added to depend on the line length, hence the dependence on -% \hsize. We call this whenever the paper size is set. -% -\def\setemergencystretch{% - \ifx\emergencystretch\thisisundefined - % Allow us to assign to \emergencystretch anyway. - \def\emergencystretch{\dimen0}% - \else - \emergencystretch = .15\hsize - \fi -} - -% Parameters in order: 1) textheight; 2) textwidth; 3) voffset; -% 4) hoffset; 5) binding offset; 6) topskip. Then whoever calls us can -% set \parskip and call \setleading for \baselineskip. -% -\def\internalpagesizes#1#2#3#4#5#6{% - \voffset = #3\relax - \topskip = #6\relax - \splittopskip = \topskip - % - \vsize = #1\relax - \advance\vsize by \topskip - \outervsize = \vsize - \advance\outervsize by 2\topandbottommargin - \pageheight = \vsize - % - \hsize = #2\relax - \outerhsize = \hsize - \advance\outerhsize by 0.5in - \pagewidth = \hsize - % - \normaloffset = #4\relax - \bindingoffset = #5\relax - % - \parindent = \defaultparindent - \setemergencystretch -} - -% @letterpaper (the default). -\def\letterpaper{{\globaldefs = 1 - \parskip = 3pt plus 2pt minus 1pt - \setleading{13.2pt}% - % - % If page is nothing but text, make it come out even. - \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}% -}} - -% Use @smallbook to reset parameters for 7x9.5 (or so) format. -\def\smallbook{{\globaldefs = 1 - \parskip = 2pt plus 1pt - \setleading{12pt}% - % - \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}% - % - \lispnarrowing = 0.3in - \tolerance = 700 - \hfuzz = 1pt - \contentsrightmargin = 0pt - \deftypemargin = 0pt - \defbodyindent = .5cm - % - \let\smalldisplay = \smalldisplayx - \let\smallexample = \smalllispx - \let\smallformat = \smallformatx - \let\smalllisp = \smalllispx -}} - -% Use @afourpaper to print on European A4 paper. -\def\afourpaper{{\globaldefs = 1 - \setleading{12pt}% - \parskip = 3pt plus 2pt minus 1pt - % - \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}% - % - \tolerance = 700 - \hfuzz = 1pt -}} - -% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin -% 29mm, hence bottom margin 28mm, nominal side margin 3cm. -\def\afourlatex{{\globaldefs = 1 - \setleading{13.6pt}% - % - \afourpaper - \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}% - % - \globaldefs = 0 -}} - -% Use @afourwide to print on European A4 paper in wide format. -\def\afourwide{% - \afourpaper - \internalpagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}% - % - \globaldefs = 0 -} - -% @pagesizes TEXTHEIGHT[,TEXTWIDTH] -% Perhaps we should allow setting the margins, \topskip, \parskip, -% and/or leading, also. Or perhaps we should compute them somehow. -% -\def\pagesizes{\parsearg\pagesizesxxx} -\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} -\def\pagesizesyyy#1,#2,#3\finish{{% - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi - \globaldefs = 1 - % - \parskip = 3pt plus 2pt minus 1pt - \setleading{13.2pt}% - % - \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}% -}} - -% Set default to letter. -% -\letterpaper - - -\message{and turning on texinfo input format.} - -% Define macros to output various characters with catcode for normal text. -\catcode`\"=\other -\catcode`\~=\other -\catcode`\^=\other -\catcode`\_=\other -\catcode`\|=\other -\catcode`\<=\other -\catcode`\>=\other -\catcode`\+=\other -\catcode`\$=\other -\def\normaldoublequote{"} -\def\normaltilde{~} -\def\normalcaret{^} -\def\normalunderscore{_} -\def\normalverticalbar{|} -\def\normalless{<} -\def\normalgreater{>} -\def\normalplus{+} -\def\normaldollar{$} - -% This macro is used to make a character print one way in ttfont -% where it can probably just be output, and another way in other fonts, -% where something hairier probably needs to be done. -% -% #1 is what to print if we are indeed using \tt; #2 is what to print -% otherwise. Since all the Computer Modern typewriter fonts have zero -% interword stretch (and shrink), and it is reasonable to expect all -% typewriter fonts to have this, we can check that font parameter. -% -\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} - -% Same as above, but check for italic font. Actually this also catches -% non-italic slanted fonts since it is impossible to distinguish them from -% italic fonts. But since this is only used by $ and it uses \sl anyway -% this is not a problem. -\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} - -% Turn off all special characters except @ -% (and those which the user can use as if they were ordinary). -% Most of these we simply print from the \tt font, but for some, we can -% use math or other variants that look better in normal text. - -\catcode`\"=\active -\def\activedoublequote{{\tt\char34}} -\let"=\activedoublequote -\catcode`\~=\active -\def~{{\tt\char126}} -\chardef\hat=`\^ -\catcode`\^=\active -\def^{{\tt \hat}} - -\catcode`\_=\active -\def_{\ifusingtt\normalunderscore\_} -% Subroutine for the previous macro. -\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} - -\catcode`\|=\active -\def|{{\tt\char124}} -\chardef \less=`\< -\catcode`\<=\active -\def<{{\tt \less}} -\chardef \gtr=`\> -\catcode`\>=\active -\def>{{\tt \gtr}} -\catcode`\+=\active -\def+{{\tt \char 43}} -\catcode`\$=\active -\def${\ifusingit{{\sl\$}}\normaldollar} -%\catcode 27=\active -%\def^^[{$\diamondsuit$} - -% Set up an active definition for =, but don't enable it most of the time. -{\catcode`\==\active -\global\def={{\tt \char 61}}} - -\catcode`+=\active -\catcode`\_=\active - -% If a .fmt file is being used, characters that might appear in a file -% name cannot be active until we have parsed the command line. -% So turn them off again, and have \everyjob (or @setfilename) turn them on. -% \otherifyactive is called near the end of this file. -\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} - -\catcode`\@=0 - -% \rawbackslashxx output one backslash character in current font -\global\chardef\rawbackslashxx=`\\ -%{\catcode`\\=\other -%@gdef@rawbackslashxx{\}} - -% \rawbackslash redefines \ as input to do \rawbackslashxx. -{\catcode`\\=\active -@gdef@rawbackslash{@let\=@rawbackslashxx }} - -% \normalbackslash outputs one backslash in fixed width font. -\def\normalbackslash{{\tt\rawbackslashxx}} - -% \catcode 17=0 % Define control-q -\catcode`\\=\active - -% Used sometimes to turn off (effectively) the active characters -% even after parsing them. -@def@turnoffactive{@let"=@normaldoublequote -@let\=@realbackslash -@let~=@normaltilde -@let^=@normalcaret -@let_=@normalunderscore -@let|=@normalverticalbar -@let<=@normalless -@let>=@normalgreater -@let+=@normalplus -@let$=@normaldollar} - -@def@normalturnoffactive{@let"=@normaldoublequote -@let\=@normalbackslash -@let~=@normaltilde -@let^=@normalcaret -@let_=@normalunderscore -@let|=@normalverticalbar -@let<=@normalless -@let>=@normalgreater -@let+=@normalplus -@let$=@normaldollar} - -% Make _ and + \other characters, temporarily. -% This is canceled by @fixbackslash. -@otherifyactive - -% If a .fmt file is being used, we don't want the `\input texinfo' to show up. -% That is what \eatinput is for; after that, the `\' should revert to printing -% a backslash. -% -@gdef@eatinput input texinfo{@fixbackslash} -@global@let\ = @eatinput - -% On the other hand, perhaps the file did not have a `\input texinfo'. Then -% the first `\{ in the file would cause an error. This macro tries to fix -% that, assuming it is called before the first `\' could plausibly occur. -% Also back turn on active characters that might appear in the input -% file name, in case not using a pre-dumped format. -% -@gdef@fixbackslash{% - @ifx\@eatinput @let\ = @normalbackslash @fi - @catcode`+=@active - @catcode`@_=@active -} - -% Say @foo, not \foo, in error messages. -@escapechar = `@@ - -% These look ok in all fonts, so just make them not special. -@catcode`@& = @other -@catcode`@# = @other -@catcode`@% = @other - -@c Set initial fonts. -@textfonts -@rm - - -@c Local variables: -@c eval: (add-hook 'write-file-hooks 'time-stamp) -@c page-delimiter: "^\\\\message" -@c time-stamp-start: "def\\\\texinfoversion{" -@c time-stamp-format: "%:y-%02m-%02d.%02H" -@c time-stamp-end: "}" -@c End: diff --git a/src/libs/termcap/tparam.c b/src/libs/termcap/tparam.c deleted file mode 100644 index 6eb6180116..0000000000 --- a/src/libs/termcap/tparam.c +++ /dev/null @@ -1,332 +0,0 @@ -/* Merge parameters into a termcap entry string. - Copyright (C) 1985, 87, 93, 95, 2000 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Emacs config.h may rename various library functions such as malloc. */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef emacs -#include "lisp.h" /* for xmalloc */ -#else - -#ifdef STDC_HEADERS -#include -#include -#else -char *malloc (); -char *realloc (); -#endif - -/* Do this after the include, in case string.h prototypes bcopy. */ -#if (defined(HAVE_STRING_H) || defined(STDC_HEADERS)) && !defined(bcopy) -#define bcopy(s, d, n) memcpy ((d), (s), (n)) -#endif - -#endif /* not emacs */ - -#ifndef NULL -#define NULL (char *) 0 -#endif - -#ifndef emacs -static void -memory_out () -{ - write (2, "virtual memory exhausted\n", 25); - exit (1); -} - -static char * -xmalloc (size) - unsigned size; -{ - register char *tem = malloc (size); - - if (!tem) - memory_out (); - return tem; -} - -static char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - register char *tem = realloc (ptr, size); - - if (!tem) - memory_out (); - return tem; -} -#endif /* not emacs */ - -/* Assuming STRING is the value of a termcap string entry - containing `%' constructs to expand parameters, - merge in parameter values and store result in block OUTSTRING points to. - LEN is the length of OUTSTRING. If more space is needed, - a block is allocated with `malloc'. - - The value returned is the address of the resulting string. - This may be OUTSTRING or may be the address of a block got with `malloc'. - In the latter case, the caller must free the block. - - The fourth and following args to tparam serve as the parameter values. */ - -static char *tparam1 (); - -/* VARARGS 2 */ -char * -tparam (string, outstring, len, arg0, arg1, arg2, arg3) - char *string; - char *outstring; - int len; - int arg0, arg1, arg2, arg3; -{ - int arg[4]; - - arg[0] = arg0; - arg[1] = arg1; - arg[2] = arg2; - arg[3] = arg3; - return tparam1 (string, outstring, len, NULL, NULL, arg); -} - -char *BC; -char *UP; - -static char tgoto_buf[50]; - -char * -tgoto (cm, hpos, vpos) - char *cm; - int hpos, vpos; -{ - int args[2]; - if (!cm) - return NULL; - args[0] = vpos; - args[1] = hpos; - return tparam1 (cm, tgoto_buf, 50, UP, BC, args); -} - -static char * -tparam1 (string, outstring, len, up, left, argp) - char *string; - char *outstring; - int len; - char *up, *left; - register int *argp; -{ - register int c; - register char *p = string; - register char *op = outstring; - char *outend; - int outlen = 0; - - register int tem; - int *old_argp = argp; - int doleft = 0; - int doup = 0; - - outend = outstring + len; - - while (1) - { - /* If the buffer might be too short, make it bigger. */ - if (op + 5 >= outend) - { - register char *new; - int offset = op - outstring; - - if (outlen == 0) - { - outlen = len + 40; - new = (char *) xmalloc (outlen); - bcopy (outstring, new, offset); - } - else - { - outlen *= 2; - new = (char *) xrealloc (outstring, outlen); - } - - op = new + offset; - outend = new + outlen; - outstring = new; - } - c = *p++; - if (!c) - break; - if (c == '%') - { - c = *p++; - tem = *argp; - switch (c) - { - case 'd': /* %d means output in decimal. */ - if (tem < 10) - goto onedigit; - if (tem < 100) - goto twodigit; - case '3': /* %3 means output in decimal, 3 digits. */ - if (tem > 999) - { - *op++ = tem / 1000 + '0'; - tem %= 1000; - } - *op++ = tem / 100 + '0'; - case '2': /* %2 means output in decimal, 2 digits. */ - twodigit: - tem %= 100; - *op++ = tem / 10 + '0'; - onedigit: - *op++ = tem % 10 + '0'; - argp++; - break; - - case 'C': - /* For c-100: print quotient of value by 96, if nonzero, - then do like %+. */ - if (tem >= 96) - { - *op++ = tem / 96; - tem %= 96; - } - case '+': /* %+x means add character code of char x. */ - tem += *p++; - case '.': /* %. means output as character. */ - if (left) - { - /* If want to forbid output of 0 and \n and \t, - and this is one of them, increment it. */ - while (tem == 0 || tem == '\n' || tem == '\t') - { - tem++; - if (argp == old_argp) - doup++, outend -= strlen (up); - else - doleft++, outend -= strlen (left); - } - } - *op++ = tem ? tem : 0200; - case 'f': /* %f means discard next arg. */ - argp++; - break; - - case 'b': /* %b means back up one arg (and re-use it). */ - argp--; - break; - - case 'r': /* %r means interchange following two args. */ - argp[0] = argp[1]; - argp[1] = tem; - old_argp++; - break; - - case '>': /* %>xy means if arg is > char code of x, */ - if (argp[0] > *p++) /* then add char code of y to the arg, */ - argp[0] += *p; /* and in any case don't output. */ - p++; /* Leave the arg to be output later. */ - break; - - case 'a': /* %a means arithmetic. */ - /* Next character says what operation. - Add or subtract either a constant or some other arg. */ - /* First following character is + to add or - to subtract - or = to assign. */ - /* Next following char is 'p' and an arg spec - (0100 plus position of that arg relative to this one) - or 'c' and a constant stored in a character. */ - tem = p[2] & 0177; - if (p[1] == 'p') - tem = argp[tem - 0100]; - if (p[0] == '-') - argp[0] -= tem; - else if (p[0] == '+') - argp[0] += tem; - else if (p[0] == '*') - argp[0] *= tem; - else if (p[0] == '/') - argp[0] /= tem; - else - argp[0] = tem; - - p += 3; - break; - - case 'i': /* %i means add one to arg, */ - argp[0] ++; /* and leave it to be output later. */ - argp[1] ++; /* Increment the following arg, too! */ - break; - - case '%': /* %% means output %; no arg. */ - goto ordinary; - - case 'n': /* %n means xor each of next two args with 140. */ - argp[0] ^= 0140; - argp[1] ^= 0140; - break; - - case 'm': /* %m means xor each of next two args with 177. */ - argp[0] ^= 0177; - argp[1] ^= 0177; - break; - - case 'B': /* %B means express arg as BCD char code. */ - argp[0] += 6 * (tem / 10); - break; - - case 'D': /* %D means weird Delta Data transformation. */ - argp[0] -= 2 * (tem % 16); - break; - - default: - abort (); - } - } - else - /* Ordinary character in the argument string. */ - ordinary: - *op++ = c; - } - *op = 0; - while (doup-- > 0) - strcat (op, up); - while (doleft-- > 0) - strcat (op, left); - return outstring; -} - -#if 0 - -main (argc, argv) - int argc; - char **argv; -{ - char buf[50]; - int args[3]; - args[0] = atoi (argv[2]); - args[1] = atoi (argv[3]); - args[2] = atoi (argv[4]); - tparam1 (argv[1], buf, "LEFT", "UP", args); - printf ("%s\n", buf); - return 0; -} - -#endif diff --git a/src/libs/termcap/version.c b/src/libs/termcap/version.c deleted file mode 100644 index e86bdc476f..0000000000 --- a/src/libs/termcap/version.c +++ /dev/null @@ -1,2 +0,0 @@ -/* Make the library identifiable with the RCS ident command. */ -static char *version_string = "\n$Version: GNU termcap 1.3.1 $\n"; diff --git a/src/preferences/appearance/FontSelectionView.cpp b/src/preferences/appearance/FontSelectionView.cpp index 9e5c0a2e55..155beea268 100644 --- a/src/preferences/appearance/FontSelectionView.cpp +++ b/src/preferences/appearance/FontSelectionView.cpp @@ -10,6 +10,7 @@ * Stephan Aßmus */ + #include "FontSelectionView.h" #include @@ -121,7 +122,8 @@ FontSelectionView::FontSelectionView(const char* name, fPreviewBox = new BBox("preview box", B_WILL_DRAW | B_FRAME_EVENTS); fPreviewBox->AddChild(BGroupLayoutBuilder(B_HORIZONTAL) .Add(fPreviewText) - .SetInsets(5, 5, 5, 5) + .SetInsets(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING, + B_USE_SMALL_SPACING, B_USE_SMALL_SPACING) .TopView() ); } diff --git a/src/preferences/backgrounds/BackgroundsView.cpp b/src/preferences/backgrounds/BackgroundsView.cpp index bcbe54849e..9e479104e5 100644 --- a/src/preferences/backgrounds/BackgroundsView.cpp +++ b/src/preferences/backgrounds/BackgroundsView.cpp @@ -1,11 +1,12 @@ /* - * Copyright 2002-2009, Haiku, Inc. All Rights Reserved. + * Copyright 2002-2013 Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: - * Jerome Duval (jerome.duval@free.fr) * Axel Dörfler, axeld@pinc-software.de + * Jerome Duval, jerome.duval@free.fr * Jonas Sundström, jonas@kirilla.se + * John Scipione, jscipione@gmail.com */ @@ -16,6 +17,7 @@ #include #include +#include #include #include #include @@ -72,8 +74,8 @@ BackgroundsView::BackgroundsView() { SetBorder(B_NO_BORDER); - fPreviewBox = new BBox("preview"); - fPreviewBox->SetLabel(B_TRANSLATE("Preview")); + BBox* previewBox = new BBox("preview"); + previewBox->SetLabel(B_TRANSLATE("Preview")); fPreview = new Preview(); @@ -101,9 +103,9 @@ BackgroundsView::BackgroundsView() } } - BView* view = BLayoutBuilder::Group<>() + previewBox->AddChild(BLayoutBuilder::Group<>() .AddGlue() - .AddGroup(B_VERTICAL, 20) + .AddGroup(B_VERTICAL, 0) .AddGroup(B_HORIZONTAL, 0) .AddGlue() .AddGrid(0, 0, 1) @@ -119,17 +121,16 @@ BackgroundsView::BackgroundsView() .End() .AddGlue() .End() - .AddGroup(B_HORIZONTAL, 10) + .AddStrut(be_control_look->DefaultItemSpacing() * 2) + .AddGroup(B_HORIZONTAL) .Add(fXPlacementText) .Add(fYPlacementText) .End() .AddGlue() - .SetInsets(10, 10, 10, 10) + .SetInsets(B_USE_DEFAULT_SPACING) .End() .AddGlue() - .View(); - - fPreviewBox->AddChild(view); + .View()); BBox* rightbox = new BBox("rightbox"); @@ -150,8 +151,8 @@ BackgroundsView::BackgroundsView() B_TRANSLATE("Other folder" B_UTF8_ELLIPSIS), new BMessage(kMsgOtherFolder))); - BMenuField* workspaceMenuField = new BMenuField(BRect(0, 0, 130, 18), - "workspaceMenuField", NULL, fWorkspaceMenu, true); + BMenuField* workspaceMenuField = new BMenuField("workspaceMenuField", + NULL, fWorkspaceMenu); workspaceMenuField->ResizeToPreferred(); rightbox->SetLabel(workspaceMenuField); @@ -162,9 +163,9 @@ BackgroundsView::BackgroundsView() fImageMenu->AddItem(new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS), new BMessage(kMsgOtherImage))); - BMenuField* imageMenuField = new BMenuField(NULL, fImageMenu); + BMenuField* imageMenuField = new BMenuField("image", + B_TRANSLATE("Image:"), fImageMenu); imageMenuField->SetAlignment(B_ALIGN_RIGHT); - imageMenuField->ResizeToPreferred(); fPlacementMenu = new BPopUpMenu(B_TRANSLATE("pick one")); fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Manual"), @@ -176,43 +177,29 @@ BackgroundsView::BackgroundsView() fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Tile"), new BMessage(kMsgTilePlacement))); - BMenuField* placementMenuField = new BMenuField(NULL, fPlacementMenu); + BMenuField* placementMenuField = new BMenuField("placement", + B_TRANSLATE("Placement:"), fPlacementMenu); placementMenuField->SetAlignment(B_ALIGN_RIGHT); fIconLabelOutline = new BCheckBox(B_TRANSLATE("Icon label outline"), new BMessage(kMsgIconLabelOutline)); fIconLabelOutline->SetValue(B_CONTROL_OFF); - fPicker = new BColorControl(BPoint(0, 0), B_CELLS_32x8, 7.0, "Picker", + fPicker = new BColorControl(BPoint(0, 0), B_CELLS_32x8, 8.0, "Picker", new BMessage(kMsgUpdateColor)); - BStringView* imageStringView = - new BStringView(NULL, B_TRANSLATE("Image:")); - BStringView* placementStringView = - new BStringView(NULL, B_TRANSLATE("Placement:")); - - imageStringView->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, - B_ALIGN_NO_VERTICAL)); - placementStringView->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, - B_ALIGN_NO_VERTICAL)); - - view = BLayoutBuilder::Group<>() - .AddGroup(B_VERTICAL, 10) - .AddGroup(B_VERTICAL, 10) - .AddGrid(10, 10) - .Add(imageStringView, 0, 0) - .Add(placementStringView, 0, 1) - .Add(imageMenuField, 1, 0) - .Add(placementMenuField, 1, 1) - .End() - .Add(fIconLabelOutline) - .End() - .Add(fPicker) - .SetInsets(10, 10, 10, 10) + rightbox->AddChild(BLayoutBuilder::Group<>(B_VERTICAL, B_USE_DEFAULT_SPACING) + .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) + .Add(imageMenuField->CreateLabelLayoutItem(), 0, 0) + .Add(imageMenuField->CreateMenuBarLayoutItem(), 1, 0) + .Add(placementMenuField->CreateLabelLayoutItem(), 0, 1) + .Add(placementMenuField->CreateMenuBarLayoutItem(), 1, 1) + .Add(fIconLabelOutline, 1, 2) .End() - .View(); - - rightbox->AddChild(view); + .AddGlue() + .Add(fPicker) + .SetInsets(B_USE_DEFAULT_SPACING) + .View()); fRevert = new BButton(B_TRANSLATE("Revert"), new BMessage(kMsgRevertSettings)); @@ -224,21 +211,21 @@ BackgroundsView::BackgroundsView() fApply->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_NO_VERTICAL)); - view = BLayoutBuilder::Group<>() - .AddGroup(B_VERTICAL, 10) - .AddGroup(B_HORIZONTAL, 10) - .Add(fPreviewBox) - .Add(rightbox) + AddChild(BLayoutBuilder::Group<>(B_VERTICAL) + .AddGroup(B_HORIZONTAL) + .AddGroup(B_VERTICAL, 0) + .AddStrut(floorf(rightbox->TopBorderOffset() + - previewBox->TopBorderOffset()) - 1) + .Add(previewBox) .End() - .AddGroup(B_HORIZONTAL, 0) - .Add(fRevert) - .Add(fApply) - .End() - .SetInsets(10, 10, 10, 10) + .Add(rightbox) .End() - .View(); - - AddChild(view); + .AddGroup(B_HORIZONTAL) + .Add(fRevert) + .Add(fApply) + .End() + .SetInsets(B_USE_DEFAULT_SPACING) + .View()); fApply->MakeDefault(true); } @@ -316,10 +303,6 @@ BackgroundsView::MessageReceived(BMessage* msg) } case kMsgManualPlacement: - _UpdatePreview(); - _UpdateButtons(); - break; - case kMsgTilePlacement: case kMsgScalePlacement: case kMsgCenterPlacement: diff --git a/src/preferences/backgrounds/BackgroundsView.h b/src/preferences/backgrounds/BackgroundsView.h index 0c80d65daf..862380701c 100644 --- a/src/preferences/backgrounds/BackgroundsView.h +++ b/src/preferences/backgrounds/BackgroundsView.h @@ -149,7 +149,6 @@ protected: BTextControl* fXPlacementText; BTextControl* fYPlacementText; Preview* fPreview; - BBox* fPreviewBox; BFilePanel* fFolderPanel; ImageFilePanel* fPanel; diff --git a/src/preferences/media/MediaWindow.cpp b/src/preferences/media/MediaWindow.cpp index 9590cb9e44..edfffc62c4 100644 --- a/src/preferences/media/MediaWindow.cpp +++ b/src/preferences/media/MediaWindow.cpp @@ -363,6 +363,7 @@ MediaWindow::_InitWindow() fContentLayout = new BCardLayout(); new BView("content view", 0, fContentLayout); fContentLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + fContentLayout->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); fAudioView = new AudioSettingsView(); fContentLayout->AddView(fAudioView); diff --git a/src/preferences/screen/ScreenWindow.cpp b/src/preferences/screen/ScreenWindow.cpp index 274393acd4..250766d3de 100644 --- a/src/preferences/screen/ScreenWindow.cpp +++ b/src/preferences/screen/ScreenWindow.cpp @@ -505,18 +505,19 @@ ScreenWindow::ScreenWindow(ScreenSettings* settings) new BMessage(BUTTON_REVERT_MSG)); fRevertButton->SetEnabled(false); - BLayoutBuilder::Group<>(this, B_VERTICAL, 10.0) - .SetInsets(10, 10, 10, 10) - .AddGroup(B_HORIZONTAL, 10.0) - .AddGroup(B_VERTICAL) - .AddStrut(floor(controlsBox->TopBorderOffset() / 16) - 1) + BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING) + .AddGroup(B_HORIZONTAL) + .AddGroup(B_VERTICAL, 0) + .AddStrut(floorf(controlsBox->TopBorderOffset()) - 1) .Add(screenBox) - .End() + .End() .Add(controlsBox) - .End() - .AddGroup(B_HORIZONTAL, 10.0) + .End() + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .Add(fRevertButton) - .AddGlue(); + .AddGlue() + .End() + .SetInsets(B_USE_DEFAULT_SPACING); _UpdateControls(); _UpdateMonitor(); diff --git a/src/preferences/time/ClockView.cpp b/src/preferences/time/ClockView.cpp index 82085c9f33..4755824014 100644 --- a/src/preferences/time/ClockView.cpp +++ b/src/preferences/time/ClockView.cpp @@ -52,6 +52,7 @@ ClockView::ClockView(const char* name) new BMessage(kShowTimeZone)); BView* view = BLayoutBuilder::Group<>(B_VERTICAL, 0) + .SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)) .Add(fShowSeconds) .Add(fShowDayOfWeek) .Add(fShowTimeZone) diff --git a/src/servers/app/Screen.cpp b/src/servers/app/Screen.cpp index 6b3b081129..0fc58008bd 100644 --- a/src/servers/app/Screen.cpp +++ b/src/servers/app/Screen.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009, Haiku, Inc. + * Copyright 2001-2013, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -140,13 +140,18 @@ Screen::SetBestMode(uint16 width, uint16 height, uint32 colorSpace, int32 index = _FindBestMode(modes, count, width, height, colorSpace, frequency); if (index < 0) { + debug_printf("app_server: Finding best mode for %ux%u (%" B_PRIu32 + ", %g Hz%s) failed\n", width, height, colorSpace, frequency, + strict ? ", strict" : ""); + if (strict) { - debug_printf("Finding best mode failed\n"); delete[] modes; return B_ERROR; } else { index = 0; // Just use the first mode in the list + debug_printf("app_server: Use %ux%u (%" B_PRIu32 ") instead.\n", + modes[0].timing.h_total, modes[0].timing.v_total, modes[0].space); } } diff --git a/src/servers/app/VirtualScreen.cpp b/src/servers/app/VirtualScreen.cpp index eb12a1abf0..94a9e1e1f2 100644 --- a/src/servers/app/VirtualScreen.cpp +++ b/src/servers/app/VirtualScreen.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2009, Haiku. + * Copyright 2005-2013, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -129,7 +129,11 @@ VirtualScreen::AddScreen(Screen* screen, ScreenConfigurations& configurations) if (status != B_OK) status = screen->SetBestMode(1024, 768, B_RGB32, 60.f); if (status != B_OK) - screen->SetBestMode(800, 600, B_RGB32, 60.f, false); + status = screen->SetBestMode(800, 600, B_RGB32, 60.f, false); + if (status != B_OK) { + debug_printf("app_server: Failed to set mode: %s\n", + strerror(status)); + } } // TODO: this works only for single screen configurations diff --git a/src/servers/cddb_daemon/cddb_server.cpp b/src/servers/cddb_daemon/cddb_server.cpp index d0d8ebb1d2..46f369e899 100644 --- a/src/servers/cddb_daemon/cddb_server.cpp +++ b/src/servers/cddb_daemon/cddb_server.cpp @@ -257,11 +257,14 @@ CDDBServer::Read(QueryResponseData* diskData, ReadResponseData* readResponse) trackData->trackNumber = track; int32 pos = line.FindFirst(" / " ); - if (pos != B_ERROR) { - // We have track specific artist information. + if (pos != B_ERROR && diskData->artist.ICompare("Various") == 0) { + // Disk is set to have a compilation artist and + // we have track specific artist information. BString artist; line.MoveInto(artist, 0, pos); + // Move artist information from line to artist. line.Remove(0, 3); + // Remove " / " from line. trackData->artist = artist; } else { trackData->artist = diskData->artist; diff --git a/src/servers/net/NetServer.cpp b/src/servers/net/NetServer.cpp index 7feb428b09..a2afcb8bb7 100644 --- a/src/servers/net/NetServer.cpp +++ b/src/servers/net/NetServer.cpp @@ -539,7 +539,11 @@ NetServer::_ConfigureInterface(BMessage& message) } // Set up IPv6 Link Local address (based on MAC, if not loopback) - _ConfigureIPv6LinkLocal(name); + + // TODO: our IPv6 stack is still fairly fragile. We need more v6 work + // (including IPv6 address scope flags before we start attaching link + // local addresses by default. + //_ConfigureIPv6LinkLocal(name); BMessage addressMessage; for (int32 index = 0; message.FindMessage("address", index, diff --git a/src/system/boot/platform/bios_ia32/long.cpp b/src/system/boot/platform/bios_ia32/long.cpp index e6728462c6..d632efc970 100644 --- a/src/system/boot/platform/bios_ia32/long.cpp +++ b/src/system/boot/platform/bios_ia32/long.cpp @@ -44,7 +44,10 @@ extern uint64 gLongKernelEntry; static inline uint64 fix_address(uint64 address) { - return address - KERNEL_LOAD_BASE + KERNEL_LOAD_BASE_64_BIT; + if(address >= KERNEL_LOAD_BASE) + return address - KERNEL_LOAD_BASE + KERNEL_LOAD_BASE_64_BIT; + else + return address; } @@ -339,9 +342,8 @@ long_start_kernel() long_gdt_init(); long_idt_init(); long_mmu_init(); - convert_kernel_args(); - debug_cleanup(); + convert_kernel_args(); // Save the kernel entry point address. gLongKernelEntry = image->elf_header.e_entry; diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp index ec71aa1294..fff96268c5 100644 --- a/src/system/kernel/device_manager/device_manager.cpp +++ b/src/system/kernel/device_manager/device_manager.cpp @@ -1552,6 +1552,7 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path) switch (subType) { case PCI_scsi: _AddPath(*stack, "busses", "scsi"); + _AddPath(*stack, "busses", "virtio"); break; case PCI_ide: _AddPath(*stack, "busses", "ata"); @@ -1583,6 +1584,7 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path) break; case PCI_network: _AddPath(*stack, "drivers", "net"); + _AddPath(*stack, "busses", "virtio"); break; case PCI_display: _AddPath(*stack, "drivers", "graphics"); @@ -1617,6 +1619,7 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path) _AddPath(*stack, "busses"); } _AddPath(*stack, "drivers", sGenericContextPath); + _AddPath(*stack, "busses/scsi"); } break; } diff --git a/src/system/kernel/device_manager/dma_resources.cpp b/src/system/kernel/device_manager/dma_resources.cpp index 71753c8414..2d7ed5f40b 100644 --- a/src/system/kernel/device_manager/dma_resources.cpp +++ b/src/system/kernel/device_manager/dma_resources.cpp @@ -92,6 +92,8 @@ DMABuffer::Dump() const DMAResource::DMAResource() + : + fScratchVecs(NULL) { mutex_init(&fLock, "dma resource"); } @@ -99,6 +101,7 @@ DMAResource::DMAResource() DMAResource::~DMAResource() { + mutex_lock(&fLock); mutex_destroy(&fLock); free(fScratchVecs); diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 1212b62df5..c5b0f7e898 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -503,7 +503,8 @@ Team::~Team() // get rid of all associated data PrepareForDeletion(); - vfs_put_io_context(io_context); + if (io_context != NULL) + vfs_put_io_context(io_context); delete_owned_ports(this); sem_delete_owned_sems(this); @@ -1706,7 +1707,9 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount, InterruptsSpinLocker teamsLocker(sTeamHashLock); sTeamHash.Insert(team); - sUsedTeams++; + bool teamLimitReached = sUsedTeams >= sMaxTeams; + if (!teamLimitReached) + sUsedTeams++; teamsLocker.Unlock(); @@ -1726,6 +1729,11 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount, // check the executable's set-user/group-id permission update_set_id_user_and_group(team, path); + if (teamLimitReached) { + status = B_NO_MORE_TEAMS; + goto err1; + } + status = create_team_arg(&teamArgs, path, flatArgs, flatArgsSize, argCount, envCount, (mode_t)-1, errorPort, errorToken); if (status != B_OK) @@ -1752,7 +1760,7 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount, status = VMAddressSpace::Create(team->id, USER_BASE, USER_SIZE, false, &team->address_space); if (status != B_OK) - goto err3; + goto err2; // create the user data area status = create_team_user_data(team); @@ -1814,8 +1822,6 @@ err5: delete_team_user_data(team); err4: team->address_space->Put(); -err3: - vfs_put_io_context(team->io_context); err2: free_team_arg(teamArgs); err1: @@ -1835,6 +1841,8 @@ err1: teamsLocker.Lock(); sTeamHash.Remove(team); + if (!teamLimitReached) + sUsedTeams--; teamsLocker.Unlock(); sNotificationService.Notify(TEAM_REMOVED, team); @@ -2039,7 +2047,9 @@ fork_team(void) InterruptsSpinLocker teamsLocker(sTeamHashLock); sTeamHash.Insert(team); - sUsedTeams++; + bool teamLimitReached = sUsedTeams >= sMaxTeams; + if (!teamLimitReached) + sUsedTeams++; teamsLocker.Unlock(); @@ -2056,6 +2066,11 @@ fork_team(void) team->debug_info.flags |= atomic_get(&parentTeam->debug_info.flags) & B_TEAM_DEBUG_INHERITED_FLAGS; + if (teamLimitReached) { + status = B_NO_MORE_TEAMS; + goto err1; + } + forkArgs = (arch_fork_arg*)malloc(sizeof(arch_fork_arg)); if (forkArgs == NULL) { status = B_NO_MEMORY; @@ -2075,7 +2090,7 @@ fork_team(void) parentTeam->realtime_sem_context); if (team->realtime_sem_context == NULL) { status = B_NO_MEMORY; - goto err25; + goto err2; } } @@ -2170,8 +2185,6 @@ err4: team->address_space->RemoveAndPut(); err3: delete_realtime_sem_context(team->realtime_sem_context); -err25: - vfs_put_io_context(team->io_context); err2: free(forkArgs); err1: @@ -2188,6 +2201,8 @@ err1: teamsLocker.Lock(); sTeamHash.Remove(team); + if (!teamLimitReached) + sUsedTeams--; teamsLocker.Unlock(); sNotificationService.Notify(TEAM_REMOVED, team); diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 7ac994cd9e..7e29df2927 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -1015,19 +1015,38 @@ thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel) } // We're going to make the thread live, now. The thread itself will take - // over a reference to its Thread object. We acquire another reference for - // our own use (and threadReference remains armed). - thread->AcquireReference(); + // over a reference to its Thread object. We'll acquire another reference + // for our own use (and threadReference remains armed). ThreadLocker threadLocker(thread); InterruptsSpinLocker schedulerLocker(gSchedulerLock); SpinLocker threadHashLocker(sThreadHashLock); + // check the thread limit + if (sUsedThreads >= sMaxThreads) { + // Clean up the user_thread structure. It's a bit unfortunate that the + // Thread destructor cannot do that, so we have to do that explicitly. + threadHashLocker.Unlock(); + schedulerLocker.Unlock(); + + user_thread* userThread = thread->user_thread; + thread->user_thread = NULL; + + threadLocker.Unlock(); + + if (userThread != NULL) + team_free_user_thread(team, userThread); + + return B_NO_MORE_THREADS; + } + // make thread visible in global hash/list thread->visible = true; sUsedThreads++; scheduler_on_thread_init(thread); + thread->AcquireReference(); + // Debug the new thread, if the parent thread required that (see above), // or the respective global team debug flag is set. But only, if a // debugger is installed for the team. diff --git a/src/system/kernel/vm/VMUserAddressSpace.cpp b/src/system/kernel/vm/VMUserAddressSpace.cpp index ac989f51db..dd10892829 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.cpp +++ b/src/system/kernel/vm/VMUserAddressSpace.cpp @@ -588,7 +588,7 @@ second_chance: } // keep walking - while (next != NULL && next->Base() + size - 1 <= end) { + while (next != NULL && next->Base() + next->Size() - 1 <= end) { addr_t alignedBase = ROUNDUP(last->Base() + last->Size(), alignment); addr_t nextBase = min_c(end, next->Base() - 1); @@ -615,8 +615,8 @@ second_chance: addr_t alignedBase = ROUNDUP(last->Base() + last->Size(), alignment); - if (is_valid_spot(last->Base() + (last->Size() - 1), alignedBase, - size, end)) { + if (next == NULL && is_valid_spot(last->Base() + (last->Size() - 1), + alignedBase, size, end)) { if (is_randomized(addressSpec)) { alignedBase = _RandomizeAddress(alignedBase, end - size + 1, diff --git a/src/system/libroot/libroot_init.c b/src/system/libroot/libroot_init.c index cf6fc668fc..867cbd25a6 100644 --- a/src/system/libroot/libroot_init.c +++ b/src/system/libroot/libroot_init.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -30,6 +31,8 @@ char *__progname = NULL; int __libc_argc; char **__libc_argv; +int __gABIVersion; + char _single_threaded = true; // determines if I/O locking needed; needed for BeOS compatibility @@ -47,6 +50,7 @@ initialize_before(image_id imageID) { char *programPath = __gRuntimeLoader->program_args->args[0]; __gCommPageAddress = __gRuntimeLoader->commpage_address; + __gABIVersion = __gRuntimeLoader->abi_version; if (programPath) { if ((__progname = strrchr(programPath, '/')) == NULL) @@ -71,6 +75,7 @@ initialize_before(image_id imageID) __init_env(__gRuntimeLoader->program_args); __init_heap_post_env(); __init_pwd_backend(); + __set_stack_protection(); } diff --git a/src/system/libroot/os/area.c b/src/system/libroot/os/area.c index 0fedf2fc48..f620d23bd0 100644 --- a/src/system/libroot/os/area.c +++ b/src/system/libroot/os/area.c @@ -5,6 +5,9 @@ #include + +#include + #include "syscalls.h" @@ -12,6 +15,8 @@ area_id create_area(const char *name, void **address, uint32 addressSpec, size_t size, uint32 lock, uint32 protection) { + if (__gABIVersion < B_HAIKU_ABI_GCC_2_HAIKU) + protection |= B_EXECUTE_AREA; return _kern_create_area(name, address, addressSpec, size, lock, protection); } @@ -20,6 +25,8 @@ area_id clone_area(const char *name, void **address, uint32 addressSpec, uint32 protection, area_id sourceArea) { + if (__gABIVersion < B_HAIKU_ABI_GCC_2_HAIKU) + protection |= B_EXECUTE_AREA; return _kern_clone_area(name, address, addressSpec, protection, sourceArea); } @@ -55,6 +62,8 @@ resize_area(area_id id, size_t newSize) status_t set_area_protection(area_id id, uint32 protection) { + if (__gABIVersion < B_HAIKU_ABI_GCC_2_HAIKU) + protection |= B_EXECUTE_AREA; return _kern_set_area_protection(id, protection); } diff --git a/src/system/libroot/os/thread.c b/src/system/libroot/os/thread.c index 7320f2924a..41721453d3 100644 --- a/src/system/libroot/os/thread.c +++ b/src/system/libroot/os/thread.c @@ -74,6 +74,23 @@ _thread_do_exit_work(void) } +void +__set_stack_protection(void) +{ + if (__gABIVersion < B_HAIKU_ABI_GCC_2_HAIKU) { + area_info info; + ssize_t cookie = 0; + + while (get_next_area_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { + if ((info.protection & B_STACK_AREA) != 0) { + _kern_set_area_protection(info.area, + B_READ_AREA | B_WRITE_AREA | B_EXECUTE_AREA | B_STACK_AREA); + } + } + } +} + + // #pragma mark - @@ -99,8 +116,11 @@ spawn_thread(thread_func entry, const char *name, int32 priority, void *data) id = _kern_spawn_thread(&attributes); if (id < 0) free(thread); - else + else { thread->id = id; + __set_stack_protection(); + } + return id; } diff --git a/src/system/libroot/posix/malloc/arch-specific.cpp b/src/system/libroot/posix/malloc/arch-specific.cpp index 54d2fe00ad..0f16100831 100644 --- a/src/system/libroot/posix/malloc/arch-specific.cpp +++ b/src/system/libroot/posix/malloc/arch-specific.cpp @@ -24,6 +24,8 @@ #include #include +#include + #include #include @@ -103,9 +105,12 @@ __init_heap(void) if (status != B_OK) sHeapBase = NULL; + uint32 protection = B_READ_AREA | B_WRITE_AREA; + if (__gABIVersion < B_HAIKU_ABI_GCC_2_HAIKU) + protection |= B_EXECUTE_AREA; sHeapArea = create_area("heap", (void **)&sHeapBase, status == B_OK ? B_EXACT_ADDRESS : B_RANDOMIZED_BASE_ADDRESS, - kInitialHeapSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + kInitialHeapSize, B_NO_LOCK, protection); if (sHeapArea < B_OK) return sHeapArea; @@ -164,6 +169,11 @@ hoardSbrk(long size) // align size request size = (size + hoardHeap::ALIGNMENT - 1) & ~(hoardHeap::ALIGNMENT - 1); + // choose correct protection flags + uint32 protection = B_READ_AREA | B_WRITE_AREA; + if (__gABIVersion < B_HAIKU_ABI_GCC_2_HAIKU) + protection |= B_EXECUTE_AREA; + hoardLock(sHeapLock); // find chunk in free list @@ -259,7 +269,7 @@ hoardSbrk(long size) && (addr_t)base + newHeapSize <= (addr_t)sHeapBase + kHeapReservationSize) { area = create_area("heap", &base, B_EXACT_ADDRESS, newHeapSize, - B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + B_NO_LOCK, protection); if (area == B_NO_MEMORY) { hoardUnlock(sHeapLock); @@ -272,7 +282,7 @@ hoardSbrk(long size) if (area < 0) { base = (void*)(sFreeHeapBase + sHeapAreaSize); area = create_area("heap", &base, B_RANDOMIZED_BASE_ADDRESS, - newHeapSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + newHeapSize, B_NO_LOCK, protection); } if (area < 0) { diff --git a/src/system/libroot/posix/pthread/pthread.cpp b/src/system/libroot/posix/pthread/pthread.cpp index 15c25165a6..1e7c4e9f96 100644 --- a/src/system/libroot/posix/pthread/pthread.cpp +++ b/src/system/libroot/posix/pthread/pthread.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -158,6 +159,7 @@ pthread_create(pthread_t* _thread, const pthread_attr_t* attr, return EAGAIN; } + __set_stack_protection(); resume_thread(thread->id); *_thread = thread; diff --git a/src/system/runtime_loader/elf_load_image.cpp b/src/system/runtime_loader/elf_load_image.cpp index b9801adb74..fd90514541 100644 --- a/src/system/runtime_loader/elf_load_image.cpp +++ b/src/system/runtime_loader/elf_load_image.cpp @@ -536,6 +536,8 @@ load_image(char const* name, image_type type, const char* rpath, #endif } + set_abi_version(image->abi); + // init gcc version dependent image flags // symbol resolution strategy if (image->abi == B_HAIKU_ABI_GCC_2_ANCIENT) diff --git a/src/system/runtime_loader/export.cpp b/src/system/runtime_loader/export.cpp index adfd2a4dd9..f8c0b068c1 100644 --- a/src/system/runtime_loader/export.cpp +++ b/src/system/runtime_loader/export.cpp @@ -57,7 +57,12 @@ struct rld_export gRuntimeLoader = { elf_reinit_after_fork, NULL, // call_atexit_hooks_for_range - terminate_program + terminate_program, + + // the following values will be set later + NULL, // program_args + NULL, // commpage_address + 0 // ABI version }; @@ -67,3 +72,16 @@ rldexport_init(void) gRuntimeLoader.program_args = gProgramArgs; gRuntimeLoader.commpage_address = __gCommPageAddress; } + + +/*! Is called for all images, and sets the minimum ABI version found to the + gRuntimeLoader.abi_version field. +*/ +void +set_abi_version(int abi_version) +{ + if (gRuntimeLoader.abi_version == 0 + || gRuntimeLoader.abi_version > abi_version) { + gRuntimeLoader.abi_version = abi_version; + } +} diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp index 754ed1193c..992dc15975 100644 --- a/src/system/runtime_loader/images.cpp +++ b/src/system/runtime_loader/images.cpp @@ -417,8 +417,10 @@ unmap_image(image_t* image) /*! This function will change the protection of all read-only segments to really - be read-only. + be read-only (and executable). The areas have to be read/write first, so that they can be relocated. + If at least one image is in compatibility mode then we allow execution of + all areas. */ void remap_images() @@ -426,14 +428,22 @@ remap_images() for (image_t* image = sLoadedImages.head; image != NULL; image = image->next) { for (uint32 i = 0; i < image->num_regions; i++) { - if ((image->regions[i].flags & RFLAG_RW) == 0 - && (image->regions[i].flags & RFLAG_REMAPPED) == 0) { - // we only need to do this once, so we remember those we've already mapped - if (_kern_set_area_protection(image->regions[i].id, - B_READ_AREA | B_EXECUTE_AREA) == B_OK) { - image->regions[i].flags |= RFLAG_REMAPPED; - } + // we only need to do this once, so we remember those we've already + // mapped + if ((image->regions[i].flags & RFLAG_REMAPPED) != 0) + continue; + + status_t result = B_OK; + if ((image->regions[i].flags & RFLAG_RW) == 0) { + result = _kern_set_area_protection(image->regions[i].id, + B_READ_AREA | B_EXECUTE_AREA); + } else if (image->abi < B_HAIKU_ABI_GCC_2_HAIKU) { + result = _kern_set_area_protection(image->regions[i].id, + B_READ_AREA | B_WRITE_AREA | B_EXECUTE_AREA); } + + if (result == B_OK) + image->regions[i].flags |= RFLAG_REMAPPED; } } } diff --git a/src/system/runtime_loader/runtime_loader_private.h b/src/system/runtime_loader/runtime_loader_private.h index b6a6cecbd9..4a0faa3ce0 100644 --- a/src/system/runtime_loader/runtime_loader_private.h +++ b/src/system/runtime_loader/runtime_loader_private.h @@ -81,6 +81,7 @@ int resolve_symbol(image_t* rootImage, image_t* image, elf_sym* sym, status_t elf_verify_header(void* header, size_t length); void rldelf_init(void); void rldexport_init(void); +void set_abi_version(int abi_version); status_t elf_reinit_after_fork(void); status_t heap_init(void); diff --git a/src/tests/kits/game/chart/ChartWindow.cpp b/src/tests/kits/game/chart/ChartWindow.cpp index a3190711c8..c75dc6058c 100644 --- a/src/tests/kits/game/chart/ChartWindow.cpp +++ b/src/tests/kits/game/chart/ChartWindow.cpp @@ -58,9 +58,9 @@ enum { H_BORDER = 5, V_BORDER = 2, ANIM_LABEL = 52, - ANIM_POPUP = 42, + ANIM_POPUP = 125, DISP_LABEL = 40, - DISP_POPUP = 42, + DISP_POPUP = 122, BUTTON_WIDTH = 50, BUTTON_OFFSET = -100, SPACE_LABEL = 40, @@ -518,12 +518,10 @@ ChartWindow::ChartWindow(BRect frame, const char *name) popup->SetFont(&font); popup->MenuBar()->SetFont(&font); popup->Menu()->SetFont(&font); - popup->ResizeToPreferred(); popup->SetDivider(popup->StringWidth(popup->Label()) + 4.0f); fTopView->AddChild(popup); - h += ANIM_LABEL + ANIM_POPUP + - popup->StringWidth(B_TRANSLATE("Slow rotation")); + h += ANIM_LABEL + ANIM_POPUP + H_BORDER; /* display mode popup */ menu = new BPopUpMenu(B_TRANSLATE("Off")); @@ -551,12 +549,10 @@ ChartWindow::ChartWindow(BRect frame, const char *name) popup->SetFont(&font); popup->MenuBar()->SetFont(&font); popup->Menu()->SetFont(&font); - popup->ResizeToPreferred(); popup->SetDivider(popup->StringWidth(popup->Label()) + 4.0f); fTopView->AddChild(popup); - h += DISP_LABEL + DISP_POPUP + - popup->StringWidth(B_TRANSLATE("DirectWindow")) + H_BORDER; + h += DISP_LABEL + DISP_POPUP + H_BORDER; /* create the offwindow (invisible) button on the left side. this will be used to record the content of the Picture diff --git a/src/tests/kits/net/Jamfile b/src/tests/kits/net/Jamfile index ce66439eab..f133901cc1 100644 --- a/src/tests/kits/net/Jamfile +++ b/src/tests/kits/net/Jamfile @@ -19,6 +19,8 @@ SimpleTest link_echo : link_echo.cpp : $(TARGET_NETWORK_LIBS) bnetapi be ; SimpleTest getpeername : getpeername.cpp : $(TARGET_NETWORK_LIBS) ; +SimpleTest if_nameindex : if_nameindex.c : $(TARGET_NETWORK_LIBS) ; + SimpleTest tcp_connection_test : tcp_connection_test.cpp : $(TARGET_NETWORK_LIBS) ; diff --git a/src/tests/kits/net/if_nameindex.c b/src/tests/kits/net/if_nameindex.c new file mode 100644 index 0000000000..60f3fbd6bc --- /dev/null +++ b/src/tests/kits/net/if_nameindex.c @@ -0,0 +1,22 @@ +#include +#include +#include + + +int main(int argc, char* argv[]) +{ + struct if_nameindex* ifs; + int i; + + ifs = if_nameindex(); + if (ifs == NULL) { + perror("if_nameindex"); + exit(EXIT_FAILURE); + } + + for (i = 0; ifs[i].if_index != 0 || ifs[i].if_name != NULL; i++) { + printf("%d %s\n", ifs[i].if_index, ifs[i].if_name); + } + + return EXIT_SUCCESS; +} diff --git a/src/tools/locale/Jamfile b/src/tools/locale/Jamfile index 1e47eaacc4..f1564b27a4 100644 --- a/src/tools/locale/Jamfile +++ b/src/tools/locale/Jamfile @@ -15,6 +15,9 @@ local localetools = # Due to the use of STL fstream open() mapping the function names via macro # name doesn't work. DEFINES += _HAIKU_BUILD_DONT_REMAP_FD_FUNCTIONS ; +# We link against the host libbe.so which could also contain this class, so +# rename it for locale tools +DEFINES += DefaultCatalog=ToolsDefaultCatalog ; USES_BE_API on $(localetools) = true ;