diff --git a/ReadMe.IntroductionToHaiku b/ReadMe.IntroductionToHaiku index f67c8e8f5f..376101dc73 100644 --- a/ReadMe.IntroductionToHaiku +++ b/ReadMe.IntroductionToHaiku @@ -58,9 +58,11 @@ This is the Haiku project's development tracker. http://haiku.it.su.se:8180/source http://grok.bikemonkey.org/source http://code.metager.de/source/xref/haiku +https://github.com/search?q=repo%3Ahaiku%2Fhaiku&type=Code Graciously provided by Janne Johansson, Landon Fuller and MetaGer respectively. This allows you to quickly and easily search Haiku's source code. +GitHub, while not {OpenGrok, also provides search functionality. Coding Guidelines diff --git a/build/jam/BuildSetup b/build/jam/BuildSetup index b839e350cc..47f346fb9a 100644 --- a/build/jam/BuildSetup +++ b/build/jam/BuildSetup @@ -145,6 +145,12 @@ if $(HAIKU_GCC_VERSION[1]) >= 4 { HAIKU_GCC_BASE_FLAGS += -Wno-array-bounds ; } +# activating graphite optimizations +if $(HAIKU_USE_GCC_GRAPHITE) = 1 { + HAIKU_GCC_BASE_FLAGS += -floop-interchange -ftree-loop-distribution + -floop-strip-mine -floop-block ; +} + if $(HOST_GCC_VERSION[1]) >= 3 { HOST_GCC_BASE_FLAGS += -fno-strict-aliasing -fno-tree-vrp ; } diff --git a/build/scripts/build_cross_tools_gcc4 b/build/scripts/build_cross_tools_gcc4 index 3f5a99696d..07c68eadc6 100755 --- a/build/scripts/build_cross_tools_gcc4 +++ b/build/scripts/build_cross_tools_gcc4 @@ -95,8 +95,7 @@ fi # (which apparently doesn't work reliably on all the different host # configurations and changes files which in turn appear as local changes # to the VCS). -find $binutilsSourceDir -name \*.info -print0 | xargs -0 touch -find $gccSourceDir -name \*.info -print0 | xargs -0 touch +find $binutilsSourceDir $gccSourceDir -name \*.info -print0 | xargs -0 touch # create the object and installation directories for the cross compilation tools installDir=$haikuOutputDir/cross-tools @@ -113,6 +112,22 @@ mkdir -p $installDir $objDir $binutilsObjDir $gccObjDir $stdcxxObjDir \ $tmpIncludeDir $tmpLibDir || exit 1 mkdir -p $installDir/lib/gcc/$haikuMachine/$gccVersion +if [ "$HAIKU_USE_GCC_GRAPHITE" = 1 ]; then + cloogSourceDir=$buildToolsDir/cloog + gmpSourceDir=$buildToolsDir/gcc/gmp + pplSourceDir=$buildToolsDir/ppl + + pplObjDir=$objDir/ppl + gmpObjDir=$objDir/gmp + cloogObjDir=$objDir/cloog + mkdir -p $pplObjDir $gmpObjDir $cloogObjDir || exit 1 + + gccConfigureArgs="$gccConfigureArgs --with-cloog=$installDir \ + --enable-cloog-backend=isl --with-ppl=$installDir \ + --disable-cloog-version-check --with-gmp=$installDir \ + --with-host-libstdcxx=\"-lstdc++\"" +fi + # force the POSIX locale, as the build (makeinfo) might choke otherwise export LC_ALL=POSIX @@ -126,6 +141,32 @@ $MAKE $additionalMakeArgs install || exit 1 export PATH=$PATH:$installDir/bin +if [ "$HAIKU_USE_GCC_GRAPHITE" = 1 ]; then + # build gmp + cd $gmpObjDir + $gmpSourceDir/configure --prefix=$installDir \ + --disable-shared --enable-cxx || exit 1 + $MAKE $additionalMakeArgs || exit 1 + $MAKE $additionalMakeArgs install || exit 1 + + # build ppl + cd $pplObjDir + CFLAGS="-O2" CXXFLAGS="-O2" $pplSourceDir/configure --prefix=$installDir \ + --disable-nls --disable-shared --disable-watchdog \ + --disable-maintainer-mode || exit 1 + $MAKE $additionalMakeArgs AUTOCONF:=true AUTOHEADER:=true ACLOCAL:=true \ + AUTOMAKE:=true || exit 1 + $MAKE $additionalMakeArgs install AUTOCONF:=true AUTOHEADER:=true \ + ACLOCAL:=true AUTOMAKE:=true || exit 1 + + # build cloog + cd $cloogObjDir + CFLAGS="-O2" CXXFLAGS="-O2" $cloogSourceDir/configure \ + --prefix=$installDir --disable-nls --disable-shared \ + --with-gmp-prefix=$installDir || exit 1 + $MAKE $additionalMakeArgs || exit 1 + $MAKE $additionalMakeArgs install || exit 1 +fi # build gcc diff --git a/configure b/configure index 1edc558802..8253afe40b 100755 --- a/configure +++ b/configure @@ -77,6 +77,8 @@ options: as first option!] --use-gcc-pipe Build with GCC option -pipe. Speeds up the build process, but uses more memory. + --use-gcc-graphite Build with GCC Graphite engine for loop + optimizations. Only for gcc 4. --use-32bit Use -m32 flag on 64bit host gcc compiler. --use-xattr Use Linux xattr support for BeOS attribute emulation. Warning: Make sure your file system @@ -170,6 +172,13 @@ standard_gcc_settings() HAIKU_GCC_RAW_VERSION=`$HAIKU_CC -dumpversion` HAIKU_GCC_MACHINE=`$HAIKU_CC -dumpmachine` + if [ "$HAIKU_USE_GCC_GRAPHITE" != 0 ]; then + UNUSED=`echo "int main() {}" | $HAIKU_CC -xc -c -floop-block - 2>&1` + if [ $? != 0 ]; then + echo "GCC Graphite loop optimizations cannot be used" + HAIKU_USE_GCC_GRAPHITE=0 + fi + fi HAIKU_GCC_LIB_DIR=${gccdir} HAIKU_GCC_LIBGCC=${gccdir}/libgcc.a @@ -345,6 +354,7 @@ HAIKU_ENABLE_MULTIUSER=0 HAIKU_DISTRO_COMPATIBILITY=default TARGET_PLATFORM=haiku HAIKU_USE_GCC_PIPE=0 +HAIKU_USE_GCC_GRAPHITE=0 HAIKU_HOST_USE_32BIT=0 HAIKU_HOST_USE_XATTR=0 HAIKU_ALTERNATIVE_GCC_OUTPUT_DIR= @@ -459,6 +469,7 @@ while [ $# -gt 0 ] ; do -j*) buildCrossToolsJobs="$1"; shift 1;; --target=*) TARGET_PLATFORM=`echo $1 | cut -d'=' -f2-`; shift 1;; --use-gcc-pipe) HAIKU_USE_GCC_PIPE=1; shift 1;; + --use-gcc-graphite) HAIKU_USE_GCC_GRAPHITE=1; shift 1;; --use-32bit) HAIKU_HOST_USE_32BIT=1; shift 1;; --use-xattr) HAIKU_HOST_USE_XATTR=1; shift 1;; *) echo Invalid argument: \`$1\'; exit 1;; @@ -519,6 +530,7 @@ mkdir -p "$buildOutputDir" || exit 1 # build cross tools from sources if [ -n "$buildCrossTools" ]; then + export HAIKU_USE_GCC_GRAPHITE "$buildCrossToolsScript" $buildCrossToolsMachine "$sourceDir" \ "$buildCrossTools" "$outputDir" $buildCrossToolsJobs || exit 1 crossToolsPrefix="$outputDir/cross-tools/bin/${HAIKU_GCC_MACHINE}-" @@ -574,6 +586,7 @@ HAIKU_INCLUDE_3RDPARTY ?= "${HAIKU_INCLUDE_3RDPARTY}" ; HAIKU_ENABLE_MULTIUSER ?= "${HAIKU_ENABLE_MULTIUSER}" ; HAIKU_DISTRO_COMPATIBILITY ?= "${HAIKU_DISTRO_COMPATIBILITY}" ; HAIKU_USE_GCC_PIPE ?= "${HAIKU_USE_GCC_PIPE}" ; +HAIKU_USE_GCC_GRAPHITE ?= "${HAIKU_USE_GCC_GRAPHITE}" ; HAIKU_HOST_USE_32BIT ?= "${HAIKU_HOST_USE_32BIT}" ; HAIKU_HOST_USE_XATTR ?= "${HAIKU_HOST_USE_XATTR}" ; HAIKU_ALTERNATIVE_GCC_OUTPUT_DIR ?= ${HAIKU_ALTERNATIVE_GCC_OUTPUT_DIR} ; diff --git a/data/catalogs/add-ons/disk_systems/intel/fr.catkeys b/data/catalogs/add-ons/disk_systems/intel/fr.catkeys index 7d67ea125d..57bb67b3ef 100644 --- a/data/catalogs/add-ons/disk_systems/intel/fr.catkeys +++ b/data/catalogs/add-ons/disk_systems/intel/fr.catkeys @@ -1,2 +1,2 @@ -1 french x-vnd.Haiku-IntelDiskAddOn 4191422532 -Active partition BFS_Creation_Parameter Partition active +1 french x-vnd.Haiku-IntelDiskAddOn 946918966 +Active partition PrimaryPartitionEditor Activer la partition diff --git a/data/catalogs/add-ons/disk_systems/intel/lt.catkeys b/data/catalogs/add-ons/disk_systems/intel/lt.catkeys index 40f694f934..239132e00c 100644 --- a/data/catalogs/add-ons/disk_systems/intel/lt.catkeys +++ b/data/catalogs/add-ons/disk_systems/intel/lt.catkeys @@ -1,2 +1,2 @@ -1 lithuanian x-vnd.Haiku-IntelDiskAddOn 4191422532 -Active partition BFS_Creation_Parameter Paleidimo skaidinys +1 lithuanian x-vnd.Haiku-IntelDiskAddOn 946918966 +Active partition PrimaryPartitionEditor Aktyvus skaidinys diff --git a/data/catalogs/add-ons/disk_systems/ntfs/fr.catkeys b/data/catalogs/add-ons/disk_systems/ntfs/fr.catkeys new file mode 100644 index 0000000000..20d6558221 --- /dev/null +++ b/data/catalogs/add-ons/disk_systems/ntfs/fr.catkeys @@ -0,0 +1,2 @@ +1 french x-vnd.Haiku-NTFSDiskAddOn 25755486 +Name: NTFS_Initialize_Parameter Label : diff --git a/data/catalogs/add-ons/disk_systems/ntfs/lt.catkeys b/data/catalogs/add-ons/disk_systems/ntfs/lt.catkeys new file mode 100644 index 0000000000..fd5e4b20ee --- /dev/null +++ b/data/catalogs/add-ons/disk_systems/ntfs/lt.catkeys @@ -0,0 +1,2 @@ +1 lithuanian x-vnd.Haiku-NTFSDiskAddOn 25755486 +Name: NTFS_Initialize_Parameter Pavadinimas: diff --git a/data/catalogs/add-ons/media/media-add-ons/multi_audio/fr.catkeys b/data/catalogs/add-ons/media/media-add-ons/multi_audio/fr.catkeys index f6d04cc00f..de15db504e 100644 --- a/data/catalogs/add-ons/media/media-add-ons/multi_audio/fr.catkeys +++ b/data/catalogs/add-ons/media/media-add-ons/multi_audio/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-hmulti_audio.media_addon 1552557772 +1 french x-vnd.Haiku-hmulti_audio.media_addon 1510080944 Master MultiAudio Général SPDIF MultiAudio SPDIF Gain MultiAudio Gain @@ -9,11 +9,16 @@ Phone MultiAudio Téléphone Aux MultiAudio Auxiliaire Output bass MultiAudio Graves Headphones MultiAudio Casque +Beep MultiAudio Bip +Output mono mix MultiAudio Sortie mélangeur mono +Output stereo mix MultiAudio Sortie mélangeur stéréo Input MultiAudio Entrée Output treble MultiAudio Aiguës +Mono mix MultiAudio Mélangeur mono General MultiAudio Général Input & Output MultiAudio Entrée & Sortie Enhanced Setup MultiAudio Réglages fins +Stereo mix MultiAudio Mélangeur stéréo Volume MultiAudio Volume Output MultiAudio Sortie Video MultiAudio Vidéo diff --git a/data/catalogs/add-ons/media/media-add-ons/multi_audio/lt.catkeys b/data/catalogs/add-ons/media/media-add-ons/multi_audio/lt.catkeys new file mode 100644 index 0000000000..e3bb797b72 --- /dev/null +++ b/data/catalogs/add-ons/media/media-add-ons/multi_audio/lt.catkeys @@ -0,0 +1,5 @@ +1 lithuanian x-vnd.Haiku-hmulti_audio.media_addon 36206598 +Master MultiAudio Pagrindinis +SPDIF MultiAudio SPDIF +Output 3D center MultiAudio 3D išvesties centras +CD MultiAudio CD diff --git a/data/catalogs/apps/activitymonitor/de.catkeys b/data/catalogs/apps/activitymonitor/de.catkeys index ac84856404..804b3d1a0f 100644 --- a/data/catalogs/apps/activitymonitor/de.catkeys +++ b/data/catalogs/apps/activitymonitor/de.catkeys @@ -1,8 +1,9 @@ -1 german x-vnd.Haiku-ActivityMonitor 3704566709 +1 german x-vnd.Haiku-ActivityMonitor 1913625522 P-faults DataSource Seitenfehler Media nodes DataSource Media-Nodes Threads DataSource Threads MB DataSource MiB +Always on top ActivityWindow Immer im Vordergrund Add graph ActivityWindow Graphen hinzufügen Teams DataSource Teams Hide legend ActivityView Legende ausblenden diff --git a/data/catalogs/apps/activitymonitor/fi.catkeys b/data/catalogs/apps/activitymonitor/fi.catkeys index 1ac04bd357..b7795140d4 100644 --- a/data/catalogs/apps/activitymonitor/fi.catkeys +++ b/data/catalogs/apps/activitymonitor/fi.catkeys @@ -1,8 +1,9 @@ -1 finnish x-vnd.Haiku-ActivityMonitor 3704566709 +1 finnish x-vnd.Haiku-ActivityMonitor 1913625522 P-faults DataSource P-viat Media nodes DataSource Mediasolmut Threads DataSource Säikeet MB DataSource Mt +Always on top ActivityWindow Aina päällimmäisenä Add graph ActivityWindow Lisää kuvaaja Teams DataSource Ryhmät Hide legend ActivityView Piilota merkin selitys diff --git a/data/catalogs/apps/activitymonitor/fr.catkeys b/data/catalogs/apps/activitymonitor/fr.catkeys index 4647fb7b5b..cf9822b5a6 100644 --- a/data/catalogs/apps/activitymonitor/fr.catkeys +++ b/data/catalogs/apps/activitymonitor/fr.catkeys @@ -1,8 +1,9 @@ -1 french x-vnd.Haiku-ActivityMonitor 3704566709 +1 french x-vnd.Haiku-ActivityMonitor 1913625522 P-faults DataSource P-fautes Media nodes DataSource Nœuds média Threads DataSource Tâches MB DataSource Mo +Always on top ActivityWindow Toujours au-dessus Add graph ActivityWindow Ajouter un graphe Teams DataSource Processus Hide legend ActivityView Cacher la légende diff --git a/data/catalogs/apps/deskbar/de.catkeys b/data/catalogs/apps/deskbar/de.catkeys index 6baf0756bc..66c87e41d1 100644 --- a/data/catalogs/apps/deskbar/de.catkeys +++ b/data/catalogs/apps/deskbar/de.catkeys @@ -1,15 +1,19 @@ -1 german x-vnd.Be-TSKB 1398106986 +1 german x-vnd.Be-TSKB 2335730970 Power off DeskbarMenu Ausschalten +Sort applications by name PreferencesWindow Laufende Anwendungen sortieren Suspend DeskbarMenu Ruhezustand Hide clock TimeView Uhr ausblenden +Applications PreferencesWindow Anwendungen Time preferences… TimeView Datum & Zeit Einstellungen… About Haiku DeskbarMenu Über Haiku +Edit in Tracker… PreferencesWindow Im Tracker bearbeiten… Recent documents: PreferencesWindow Letzte Dokumente: Recent applications DeskbarMenu Letzte Anwendungen Applications B_USER_DESKBAR_DIRECTORY/Applications Anwendungen Find… DeskbarMenu Suchen… Show clock Tray Uhr anzeigen Window PreferencesWindow Fenster +Defaults PreferencesWindow Standardwerte Menu PreferencesWindow Menü Recent documents DeskbarMenu Letzte Dokumente Auto-hide PreferencesWindow Automatisch ausblenden @@ -27,6 +31,7 @@ Restart Tracker DeskbarMenu Tracker neu starten Close all WindowMenu Alle schließen Deskbar preferences PreferencesWindow Deskbar-Einstellungen Mount DeskbarMenu Einhängen +Revert PreferencesWindow Anfangswerte Small PreferencesWindow Klein Recent applications: PreferencesWindow Letzte Anwendungen: Shutdown… DeskbarMenu Herunterfahren… diff --git a/data/catalogs/apps/deskbar/fi.catkeys b/data/catalogs/apps/deskbar/fi.catkeys index 5a7f9bc06f..00376576a7 100644 --- a/data/catalogs/apps/deskbar/fi.catkeys +++ b/data/catalogs/apps/deskbar/fi.catkeys @@ -1,16 +1,19 @@ -1 finnish x-vnd.Be-TSKB 1042823442 +1 finnish x-vnd.Be-TSKB 2335730970 Power off DeskbarMenu Sammuta virta +Sort applications by name PreferencesWindow Lajittele sovellukset nimen perusteella Suspend DeskbarMenu Keskeytystila Hide clock TimeView Piilota kello Applications PreferencesWindow Sovellukset Time preferences… TimeView Aika-asetukset... About Haiku DeskbarMenu Haikusta +Edit in Tracker… PreferencesWindow Muokkaa Seuraajassa… Recent documents: PreferencesWindow Äskettäiset asiakirjat: Recent applications DeskbarMenu Äskettäiset sovellukset Applications B_USER_DESKBAR_DIRECTORY/Applications Sovellukset Find… DeskbarMenu Etsi... Show clock Tray Näytä kello Window PreferencesWindow Ikkuna +Defaults PreferencesWindow Oletukset Menu PreferencesWindow Valikko Recent documents DeskbarMenu Äskettäiset asiakirjat Auto-hide PreferencesWindow Piilota automaattisesti @@ -28,6 +31,7 @@ Restart Tracker DeskbarMenu Käynnistä Seuraaja uudelleen Close all WindowMenu Sulje kaikki Deskbar preferences PreferencesWindow Työpöytäpalkin asetukset Mount DeskbarMenu Liitä +Revert PreferencesWindow Palauta Small PreferencesWindow Pieni Recent applications: PreferencesWindow Äskettäiset sovellukset: Shutdown… DeskbarMenu Sammuttaminen... diff --git a/data/catalogs/apps/deskbar/fr.catkeys b/data/catalogs/apps/deskbar/fr.catkeys index e1122b80dd..f7731a1988 100644 --- a/data/catalogs/apps/deskbar/fr.catkeys +++ b/data/catalogs/apps/deskbar/fr.catkeys @@ -1,5 +1,6 @@ -1 french x-vnd.Be-TSKB 1042823442 +1 french x-vnd.Be-TSKB 4028879882 Power off DeskbarMenu Éteindre +Sort applications by name PreferencesWindow Trier les applications par nom Suspend DeskbarMenu Mettre en veille Hide clock TimeView Masquer l'horloge Applications PreferencesWindow Applications diff --git a/data/catalogs/apps/drivesetup/fr.catkeys b/data/catalogs/apps/drivesetup/fr.catkeys index b459f00aeb..7c1e619ab3 100644 --- a/data/catalogs/apps/drivesetup/fr.catkeys +++ b/data/catalogs/apps/drivesetup/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-DriveSetup 1767229522 +1 french x-vnd.Haiku-DriveSetup 12870063 DriveSetup System name Gestionnaire de disque Cancel AbstractParametersPanel Annuler Delete MainWindow Supprimer @@ -18,6 +18,7 @@ The selected disk is read-only. MainWindow Le disque choisi est en lecture seul Are you sure you want to format the partition \"%s\"? You will be asked again before changes are written to the disk. MainWindow Êtes-vous sûr de vouloir formater la partition « %s » ? Une confirmation vous sera à nouveau demandée avant que les changements ne soient écrits sur le disque. Could not mount partition %s. MainWindow Impossible de monter la partition %s. The partition %s has been successfully formatted.\n MainWindow La partition %s a été correctement formatée.\n +Change parameters MainWindow Modifier les paramètres The partition %s is already unmounted. MainWindow La partition %s est déjà démontée. Failed to delete the partition. No changes have been written to disk. MainWindow Impossible de supprimer la partition. Aucun changement n'a été écrit sur le disque. Could not delete the selected partition. MainWindow Impossible de supprimer la partition sélectionnée. @@ -36,39 +37,50 @@ Write changes MainWindow Écrire les modifications There was an error preparing the disk for modifications. MainWindow Une erreur est survenue pendant la préparation des modifications du disque. The partition %s is already mounted. MainWindow La partition %s est déjà montée. Are you sure you want to format the partition? You will be asked again before changes are written to the disk. MainWindow Êtes-vous sûr de vouloir formater la partition ? Une confirmation vous sera à nouveau demandée avant que les changements ne soient écrits sur le disque. +Partition name: ChangeParametersPanel Label de partition : +Change ChangeParametersPanel Modifier 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 Êtes-vous sûr de vouloir écrire les modifications sur disque maintenant ?\n\nToutes les données du disque %s seront irrémédiablement perdues si vous le faites ! 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 Êtes-vous sûr de vouloir supprimer la partition sélectionnée ?\n\nToutes les données sur la partition seront définitivement perdues si vous le faites ! Create… MainWindow Créer… Disk system \"%s\"\" not found! MainWindow Le disque système « %s » est introuvable ! The disk has been successfully initialized.\n MainWindow Le disque a été correctement initialisée.\n Could not unmount partition %s. MainWindow Impossible de démonter la partition %s. +Failed to change the parameters of the partition. No changes have been written to disk. MainWindow La modification des paramètres de la partition a échoué. Aucune modification n'a été écrite sur le disque. Failed to format the partition %s!\n MainWindow Impossible de formater la partition %s !\n Mount MainWindow Monter Partition type PartitionList Type de partition 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 Êtes-vous sûr de vouloir formater un disque brut ? (la plus part du temps, il convient au préalable d'initialiser le disque avec un système de partitions ) Une confirmation vous sera à nouveau demandée avant que les changements ne soient écrits sur le disque. +The panel experienced a problem! MainWindow La fenêtre a rencontré un problème ! +Change parameters… MainWindow Modifier les paramètres… Device PartitionList Périphérique Disk MainWindow Disque 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 Êtes-vous sûr de vouloir initialiser le disque sélectionné ? Toutes les données seront perdues. Une confirmation vous sera à nouveau demandée avant que les changements ne soient écrits sur le disque.\n +Partition size CreateParametersPanel Taille de la partition Device DiskView Périphérique Active PartitionList Active Volume name PartitionList Nom de volume Continue MainWindow Continuer Cannot delete the selected partition. MainWindow La partition sélectionnée ne peut pas être supprimée. Mount all MainWindow Monter tout +End: %s Support Fin : %s Cancel MainWindow Annuler Delete partition MainWindow Supprimer la partition Eject MainWindow Éjecter Partition MainWindow Partition +Create CreateParametersPanel Créer File system PartitionList Système de fichiers Validation of the given creation parameters failed. MainWindow Le contrôle des paramètres de création donnés a échoué. +Partition type: ChangeParametersPanel Type de la partition : Size PartitionList Taille Wipe (not implemented) MainWindow Effacer (non implémenté) Validation of the given initialization parameters failed. MainWindow Le contrôle des paramètres d'initialisation donnés a échoué. The selected partition does not contain a partitioning system. MainWindow La partition sélectionnée ne contient pas de système de partitionnement. +Offset: %s Support Offset : %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 Êtes-vous sûr de vouloir enregistrer les modifications sur le disque maintenant ?\n\nToutes les données sur la partition %s seront définitivement perdues si vous le faites ! The partition %s is currently mounted. MainWindow La partition %s est actuellement montée. Surface test (not implemented) MainWindow Test de surface (non implémenté) Format MainWindow Formater +Could not change the parameters of the selected partition. MainWindow Impossible de modifier les paramètres de la partition sélectionnée. Parameters PartitionList Paramètres Creation of the partition has failed. MainWindow La partition n'a pas pu être créée. The currently selected partition is not empty. MainWindow La partition sélectionnée n'est pas vide. diff --git a/data/catalogs/apps/drivesetup/zh_Hans.catkeys b/data/catalogs/apps/drivesetup/zh_Hans.catkeys index e07cce5d4f..31bc29df38 100644 --- a/data/catalogs/apps/drivesetup/zh_Hans.catkeys +++ b/data/catalogs/apps/drivesetup/zh_Hans.catkeys @@ -1,11 +1,14 @@ -1 english x-vnd.Haiku-DriveSetup 644135944 +1 english x-vnd.Haiku-DriveSetup 1752326393 DriveSetup System name 磁盘管理器 +Cancel AbstractParametersPanel 取消 Delete MainWindow 删除 Are you sure you want to write the changes back to disk now?\n\nAll data on the selected partition will be irretrievably lost if you do so! MainWindow 您确定将所做修改写入磁盘吗?\n\n如果执行此操作,选中分区上的所有数据将丢失,无法恢复! Rescan MainWindow 重新扫描 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 确定 PartitionList <空白> Unable to find the selected partition by ID. MainWindow 无法通过ID找到所选分区。 Select a partition from the list below. DiskView 请从以下列表选择一个分区。 diff --git a/data/catalogs/apps/firstbootprompt/fr.catkeys b/data/catalogs/apps/firstbootprompt/fr.catkeys index ca0903961b..8f8d9a6c79 100644 --- a/data/catalogs/apps/firstbootprompt/fr.catkeys +++ b/data/catalogs/apps/firstbootprompt/fr.catkeys @@ -1,5 +1,6 @@ -1 french x-vnd.Haiku-FirstBootPrompt 988630706 +1 french x-vnd.Haiku-FirstBootPrompt 2649051796 Custom BootPromptWindow Personnalisé +Boot to Desktop BootPromptWindow Démarrer le bureau 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 .\" Merci d'essayer Haiku ! Nous espérons que vous l'aimerez !\n\nVeuillez choisir votre clavier et votre langue préférés dans la liste à gauche. Ils seront pris en compte instantanément. Plus tard, vous pourrez facilement modifier à la volée ces deux réglages à partir du bureau.\n\nVoulez-vous exécuter le programme d'installation ou continuer le démarrage du bureau ?\n\nNote : La traduction des applications et des autres parties d'Haiku n'est pas terminée. Vous trouverez souvent des phrases non traduites, mais si vous le souhaitez, vous pouvez apporter votre contribution sur .\n Language BootPromptWindow Langue Welcome to Haiku! BootPromptWindow Bienvenue dans Haiku ! diff --git a/data/catalogs/apps/launchbox/fi.catkeys b/data/catalogs/apps/launchbox/fi.catkeys index 8186bca965..9af8e6218b 100644 --- a/data/catalogs/apps/launchbox/fi.catkeys +++ b/data/catalogs/apps/launchbox/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-LaunchBox 3016105370 +1 finnish x-vnd.Haiku-LaunchBox 3692177981 New LaunchBox Uusi Set description… LaunchBox Aseta kuvaus... Vertical layout LaunchBox Pystysuora sijoittelu @@ -6,6 +6,7 @@ OK LaunchBox Valmis Pad 1 LaunchBox Alusta 1 last chance LaunchBox viimeinen mahdollisuus Quit LaunchBox Poistu +Open containing folder LaunchBox Avaa sisältyvä kansio Clear button LaunchBox Nollaa painike LaunchBox System name Käynnistysikkuna Ignore double-click LaunchBox Ohita kaksoisnapsautukset diff --git a/data/catalogs/apps/launchbox/fr.catkeys b/data/catalogs/apps/launchbox/fr.catkeys index 41d45a0fa5..2180e612f3 100644 --- a/data/catalogs/apps/launchbox/fr.catkeys +++ b/data/catalogs/apps/launchbox/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-LaunchBox 3016105370 +1 french x-vnd.Haiku-LaunchBox 3692177981 New LaunchBox Nouveau Set description… LaunchBox Ajouter une description… Vertical layout LaunchBox Disposition verticale @@ -6,6 +6,7 @@ OK LaunchBox OK Pad 1 LaunchBox Pavé 1 last chance LaunchBox dernière chance Quit LaunchBox Quitter +Open containing folder LaunchBox Ouvrir le dossier hôte Clear button LaunchBox Vider le bouton LaunchBox System name Lanceur rapide Ignore double-click LaunchBox Ignorer le double click diff --git a/data/catalogs/apps/terminal/de.catkeys b/data/catalogs/apps/terminal/de.catkeys index c6250e02b3..13d8e23b39 100644 --- a/data/catalogs/apps/terminal/de.catkeys +++ b/data/catalogs/apps/terminal/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-Terminal 2645209895 +1 german x-vnd.Haiku-Terminal 2967760334 Not found. Terminal TermWindow Nicht gefunden. Switch Terminals Terminal TermWindow Terminals wechseln Change directory Terminal TermView Zum Ordner wechseln @@ -62,7 +62,6 @@ Text not found. Terminal TermWindow Der Suchbegriff wurde nicht gefunden. Find… Terminal TermWindow Suchen... The process \"%1\" is still running.\nIf you close the Terminal, the process will be killed. Terminal TermWindow Der Prozess \"%1\" läuft noch.\nWird das Terminal geschlossen, wird auch dieser Prozess abgebrochen. Move here Terminal TermView Hierher verschieben -\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%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-\tArbeitsverzeichnis des gerade im aktuellen Reiter\n\t\t\tlaufenden Prozesses. Optional kann auch die maximale\n\t\t\tAnzahl der Pfadkomponenten angegeben werden.\n\t\t\tZum Beispiel: '%2d' für maximal zwei Komponenten.\n\t%T\t-\tName der Terminalanwendung in der aktuellen Systemsprache\n\t%i\t-\tLaufende Nummer des Fensters\n\t%p\t-\tName des laufenden Prozesses im aktuellen Reiter\n\t%t\t-\tTitel des aktuellen Reiters\n\t%%\t-\tDas Zeichen '%' Retro Terminal colors scheme Retro Error! Terminal getString Fehler! New tab Terminal TermWindow Neuer Reiter @@ -80,6 +79,7 @@ Clear all Terminal TermWindow Bildschirm leeren Text encoding Terminal TermWindow Kodierung size Terminal TermView Größe Close window Terminal TermWindow Fenster schließen +\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-\tArbeitsverzeichnis des gerade im aktuellen Reiter\n\t\t\tlaufenden Prozesses. Optional kann auch die maximale\n\t\t\tAnzahl der Pfadkomponenten angegeben werden.\n\t\t\tZum Beispiel: '%2d' für maximal zwei Komponenten.\n\t%T\t-\tName der Terminalanwendung in der aktuellen Systemsprache\n\t%T\t-\tKodierung des aktuellen Reiters. Unterdrückt bei UTF-8\n\t%i\t-\tLaufende Nummer des Fensters\n\t%p\t-\tName des laufenden Prozesses im aktuellen Reiter\n\t%t\t-\tTitel des aktuellen Reiters\n\t%%\t-\tDas Zeichen '%' Save as default Terminal TermWindow Als Standard speichern Set tab title Terminal TermWindow Reiter umbenennen Settings… Terminal TermWindow Einstellungen... diff --git a/data/catalogs/apps/terminal/fi.catkeys b/data/catalogs/apps/terminal/fi.catkeys index bff140c840..22afe4c154 100644 --- a/data/catalogs/apps/terminal/fi.catkeys +++ b/data/catalogs/apps/terminal/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-Terminal 2645209895 +1 finnish x-vnd.Haiku-Terminal 2967760334 Not found. Terminal TermWindow Ei löytynyt. Switch Terminals Terminal TermWindow Vaihda pääteikkunoita Change directory Terminal TermView Vaihda hakemistoa @@ -62,7 +62,6 @@ Text not found. Terminal TermWindow Tekstiä ei löydy. Find… Terminal TermWindow Etsi... The process \"%1\" is still running.\nIf you close the Terminal, the process will be killed. Terminal TermWindow Prosessia ”%1” suoritetaan yhä.\nJos suljet Pääteikkunan, prosessi tapetaan. Move here Terminal TermView Siirrä tänne -\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%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-\tAktiivin prosessin nykyinen työhakemisto on nykyisessä\n\t\t\tvälilehdessä. Valinnaisesti voidaan määritellä polkukomponenttien\n\t\t\tenimmäismäärä. Esim.: '%2d' vähintään kahdelle komponentille.\n\t%T\t-\tPääteikkunan nimi nykyisillä paikallisasetuksilla.\n\t%i\t-\tIkkunaindeksi.\n\t%p\t-\tAktiivin prosessin nimi nykyisessä välilehdessä.\n\t%t\t-\tThe title of the current tab.\n\t%%\t-\tMerkki '%'. Retro Terminal colors scheme Retro Error! Terminal getString Virhe! New tab Terminal TermWindow Uusi välilehti @@ -80,6 +79,7 @@ Clear all Terminal TermWindow Tyhjennä kaikki Text encoding Terminal TermWindow Tekstikoodaus size Terminal TermView koko Close window Terminal TermWindow Sulje ikkuna +\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-\tAktiivin prosessin työhakemisto nykyisessä\n\t\t\tvälilehdessä. Valinnaisesti voidaan määritellä polkukompo-\n\t\t\tnenttien enimmäismäärä. Esim.: '%2d' useimmille kahdelle komponentille.\n\t%T\t-\tPääteikkunasovelluksen nimi nykyiselle paikallisasetukselle.\n\t%e\t-\tNykyisen välilehden koodaus. Ei näytetä, jos koodaus on UTF-8.\n\t%i\t-\tIkkunan indeksi.\n\t%p\t-\tAktiivin prosessin nimi nykyisessä välilehdessä.\n\t%t\t-\tNykyisen välilehden otsikko.\n\t%%\t-\tKirjain '%'. Save as default Terminal TermWindow Tallenna oletuksena Set tab title Terminal TermWindow Aseta välilehtiotsikko Settings… Terminal TermWindow Asetukset... diff --git a/data/catalogs/apps/terminal/fr.catkeys b/data/catalogs/apps/terminal/fr.catkeys index 3dd76ff91d..28084e1806 100644 --- a/data/catalogs/apps/terminal/fr.catkeys +++ b/data/catalogs/apps/terminal/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-Terminal 766764238 +1 french x-vnd.Haiku-Terminal 328707356 Not found. Terminal TermWindow Non trouvé. Switch Terminals Terminal TermWindow Inverser les Terminaux Change directory Terminal TermView Changer de répertoire @@ -21,6 +21,7 @@ Font: Terminal AppearancePrefView Police : Copy here Terminal TermView Copier ici Really close? Terminal TermWindow Êtes-vous sûr de vouloir fermer ? Copy Terminal TermWindow Copier +Terminal Terminal TermWindow The title for the main window menubar entry related to terminal sessions Terminal Color scheme: Terminal AppearancePrefView Profil de couleurs : Window title: Terminal TermWindow Titre de la fenêtre : Unrecognized option \"%s\"\n Terminal arguments parsing Option « %s » non reconnue\n diff --git a/data/catalogs/apps/terminal/hu.catkeys b/data/catalogs/apps/terminal/hu.catkeys index 263e4a589a..b49518bc61 100644 --- a/data/catalogs/apps/terminal/hu.catkeys +++ b/data/catalogs/apps/terminal/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Haiku-Terminal 2645209895 +1 hungarian x-vnd.Haiku-Terminal 2967760334 Not found. Terminal TermWindow Nem található. Switch Terminals Terminal TermWindow Terminálok közti váltás Change directory Terminal TermView Mappa váltása @@ -62,7 +62,6 @@ Text not found. Terminal TermWindow Nem található a szöveg. Find… Terminal TermWindow Keresés… The process \"%1\" is still running.\nIf you close the Terminal, the process will be killed. Terminal TermWindow A folyamat (%1) még fut.\nHa bezárja a Terminált, a folyamat megszakad. Move here Terminal TermView Mozgatás -\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%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-\tAz aktuális fülön belül épp futó folyamat munka-mappája.\n\t\t\tTovábbá az útvonal elemeinek a maximális száma is megadható.\n\t\t\tPéldául '%2d' maximum 2 elem megjelenítéséhez.\n\t%T\t-\tA Terminál program neve az aktuális nyelven.\n\t%i\t-\tAz ablak sorszáma.\n\t%p\t-\tA fülön futtatott folyamat neve.\n\t%t\t-\tAz aktuális fül címe.\n\t%%\t-\t'%' karakter. Retro Terminal colors scheme Retro Error! Terminal getString Hiba! New tab Terminal TermWindow Új lap @@ -80,6 +79,7 @@ Clear all Terminal TermWindow Összes törlése Text encoding Terminal TermWindow Szöveg kódolása size Terminal TermView méret Close window Terminal TermWindow Ablak bezárása +\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 A jelenlegi mappa az aktuális fülön.\n\t \t \t Kiegészítésként a maximálisan megjelenő mappá száma\n\t \t \t is megadható. Például '%2d' a legutóbbi 2 részre.\n\t %T\t -\t A Terminál program neve az aktuális nyelven.\n\t %e\t -\t Az aktuális fül kódolása. UTF-8 esetében nem jelenik meg.\n\t %i\t -\t Az ablak sorszáma.\n\t %p\t -\t Az aktív parancs neve az aktuális fülön.\n\t %t\t -\t Aktuális fül címe.\n\t %%\t -\t '%' karakter. Save as default Terminal TermWindow Mentés alapértelmezettként Set tab title Terminal TermWindow Lap címének beállítása Settings… Terminal TermWindow Beállítások… diff --git a/data/catalogs/apps/terminal/ja.catkeys b/data/catalogs/apps/terminal/ja.catkeys index 6902d6f274..2cf3c22137 100644 --- a/data/catalogs/apps/terminal/ja.catkeys +++ b/data/catalogs/apps/terminal/ja.catkeys @@ -1,4 +1,4 @@ -1 japanese x-vnd.Haiku-Terminal 2645209895 +1 japanese x-vnd.Haiku-Terminal 2967760334 Not found. Terminal TermWindow これ以上見つかりません。 Switch Terminals Terminal TermWindow ターミナルを切替える Change directory Terminal TermView ディレクトリを変更 @@ -62,7 +62,6 @@ Text not found. Terminal TermWindow 検索テキストが見つかりません Find… Terminal TermWindow 検索… The process \"%1\" is still running.\nIf you close the Terminal, the process will be killed. Terminal TermWindow プロセス \"%1\" がまだ実行中です。\nTerminalを閉じると強制終了されます。 Move here Terminal TermView カレントディレクトリへ移動 -\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%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現在のロケールでの Terminal アプリケーションの名前\n\t%i\t-\tウィンドウのインデックス\n\t%p\t-\t動作中のプロセス名を現在のタブに表示\n\t%t\t-\t現在のタブのタイトル\n\t%%\t-\t文字 '%' Retro Terminal colors scheme レトロ Error! Terminal getString エラー! New tab Terminal TermWindow 新しいタブ @@ -80,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現在のロケールでの Terminal アプリケーション名\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/pl.catkeys b/data/catalogs/apps/terminal/pl.catkeys index 99727e84dc..1c09daa7a0 100644 --- a/data/catalogs/apps/terminal/pl.catkeys +++ b/data/catalogs/apps/terminal/pl.catkeys @@ -1,4 +1,4 @@ -1 polish x-vnd.Haiku-Terminal 2645209895 +1 polish x-vnd.Haiku-Terminal 328707356 Not found. Terminal TermWindow Nie znaleziono. Switch Terminals Terminal TermWindow Przełącz Terminal Change directory Terminal TermView Zmień folder @@ -62,7 +62,6 @@ Text not found. Terminal TermWindow Tekst nie znaleziony. Find… Terminal TermWindow Znajdź… The process \"%1\" is still running.\nIf you close the Terminal, the process will be killed. Terminal TermWindow Proces \"%1\" jest wciąż w użyciu.\nJeśli zamkniesz terminal, proces zostanie zatrzymany. Move here Terminal TermView Przenieś tutaj -\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%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-\tBieżący katalog roboczy dla aktywnego procesu w danej\n\t\t\tzakładce. Opcjonalnie maksymalna liczba elementów ścieżki\n\t\t\tjaka ma być określona. Np. '%2d' dla co najwyżej dwóch elementów.\n\t%T\t-\tNazwa programu Terminala dla obecnych ustawień localizacyjnych (locale).\n\t%i\t-\tLiczba porządkowa okna (index).\n\t%p\t-\tNazwa aktywnego okna w bieżącej zakładce.\n\t%t\t-\tTytuł bieżącej zakładki.\n\t%%\t-\tZnak '%'. Retro Terminal colors scheme Retro Error! Terminal getString Błąd! New tab Terminal TermWindow Nowa karta diff --git a/data/catalogs/apps/terminal/pt_BR.catkeys b/data/catalogs/apps/terminal/pt_BR.catkeys index 1a409ae55f..3ed2a75e3d 100644 --- a/data/catalogs/apps/terminal/pt_BR.catkeys +++ b/data/catalogs/apps/terminal/pt_BR.catkeys @@ -1,4 +1,4 @@ -1 portuguese (brazil) x-vnd.Haiku-Terminal 2645209895 +1 portuguese (brazil) x-vnd.Haiku-Terminal 328707356 Not found. Terminal TermWindow Não localizado. Switch Terminals Terminal TermWindow Alternar Terminais Change directory Terminal TermView Mudar de pasta @@ -62,7 +62,6 @@ Text not found. Terminal TermWindow Texto não encontrado. Find… Terminal TermWindow Localizar… The process \"%1\" is still running.\nIf you close the Terminal, the process will be killed. Terminal TermWindow O processo \"%1\" ainda está executando.\nSe fechar o Terminal, o processo será morto. Move here Terminal TermView Mover aqui -\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%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 O diretório de trabalho atual do processo ativo na\n\t \t\t aba atual. Opcionalmente o número máximo de componentes do caminho\n\t \t\t pode ser especificado. Por exemplo, '%2d' para no máximo dois componentes.\n\t %T\t -\t O nome do aplicativo Terminal para a localidade atual.\n\t %i\t -\t O índice da janela.\n\t %p\t -\t O nome do processo ativo na guia atual.\n\t %t\t -\t O título da guia atual.\n\t %%\t -\t O caractere '%'. Retro Terminal colors scheme Retrô Error! Terminal getString Erro! New tab Terminal TermWindow Nova aba diff --git a/data/catalogs/apps/terminal/ru.catkeys b/data/catalogs/apps/terminal/ru.catkeys index 6426764b45..b6d2f1fd58 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 2645209895 +1 russian x-vnd.Haiku-Terminal 328707356 Not found. Terminal TermWindow Текст не найден Switch Terminals Terminal TermWindow Переключить терминалы Change directory Terminal TermView Сменить каталог @@ -62,7 +62,6 @@ Text not found. Terminal TermWindow Текст не найден Find… Terminal TermWindow Найти… The process \"%1\" is still running.\nIf you close the Terminal, the process will be killed. Terminal TermWindow Процесс \"%1\" все еще работает.\nЕсли вы закроете Терминал, то этот процесс будет уничтожен. Move here Terminal TermView Переместить сюда -\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%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%i\t-\tНомер окна.\n\t%p\t-\tНазвание активного процесса в текущей вкладке.\n\t%t\t-\tЗаголовок текущей вкладки.\n\t%%\t-\tСимвол процента - '%'. Retro Terminal colors scheme Ретро Error! Terminal getString Ошибка! New tab Terminal TermWindow Новая вкладка diff --git a/data/catalogs/apps/terminal/sv.catkeys b/data/catalogs/apps/terminal/sv.catkeys index 109c858073..0daa3e3a83 100644 --- a/data/catalogs/apps/terminal/sv.catkeys +++ b/data/catalogs/apps/terminal/sv.catkeys @@ -1,4 +1,4 @@ -1 swedish x-vnd.Haiku-Terminal 2645209895 +1 swedish x-vnd.Haiku-Terminal 328707356 Not found. Terminal TermWindow Hittades ej. Switch Terminals Terminal TermWindow Växla terminal Change directory Terminal TermView Byt katalog @@ -62,7 +62,6 @@ Text not found. Terminal TermWindow Text hittades inte. Find… Terminal TermWindow Sök... The process \"%1\" is still running.\nIf you close the Terminal, the process will be killed. Terminal TermWindow Processen \"%1\" körs fortfarande.\nOm du stänger Terminalen kommer processen att termineras. Move here Terminal TermView Flytta hit -\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%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 Arbetskatalogen till den aktiva processen på den valda tabben\n\t\t\t eller de maximala antal sökvägs komponenter kan bli specificerade.\n\t\t\t E.g. '%2d' för att ange två komponenter.\n\t%T\t-\tTerminal applikationsnamnet för denna översättning.\n\t%i\t-\t Indexet för detta fönster.\n\t%p\t-\tNamnet på den aktiva processen io den valda tabben.\n\t%t\t-\tNamnet på den valda tabben.\n\t%%\t-\t Tecknet '%'. Retro Terminal colors scheme Retro Error! Terminal getString Fel! New tab Terminal TermWindow Ny flik diff --git a/data/catalogs/apps/terminal/zh_Hans.catkeys b/data/catalogs/apps/terminal/zh_Hans.catkeys index c6dc7932bc..f019405269 100644 --- a/data/catalogs/apps/terminal/zh_Hans.catkeys +++ b/data/catalogs/apps/terminal/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-Terminal 766764238 +1 english x-vnd.Haiku-Terminal 328707356 Not found. Terminal TermWindow 未找到。 Switch Terminals Terminal TermWindow 切换终端 Change directory Terminal TermView 更改目录 @@ -21,6 +21,7 @@ Font: Terminal AppearancePrefView 字体: Copy here Terminal TermView 复制到此 Really close? Terminal TermWindow 确定关闭吗? Copy Terminal TermWindow 复制 +Terminal Terminal TermWindow The title for the main window menubar entry related to terminal sessions 终端 Color scheme: Terminal AppearancePrefView 色彩模式: Window title: Terminal TermWindow 窗口标题: Unrecognized option \"%s\"\n Terminal arguments parsing 无法识别的选项\"%s\"\n diff --git a/data/catalogs/apps/webpositive/fi.catkeys b/data/catalogs/apps/webpositive/fi.catkeys index f72e0505d4..f2686dbf2d 100644 --- a/data/catalogs/apps/webpositive/fi.catkeys +++ b/data/catalogs/apps/webpositive/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-WebPositive 233049275 +1 finnish x-vnd.Haiku-WebPositive 3577331897 Show home button Settings Window Näytä aloitussivupainike Username: Authentication Panel Käyttäjätunnus: Copy URL to clipboard Download Window Kopioi verkko-osoite leikepöydälle @@ -16,6 +16,7 @@ Start page: Settings Window Aloitussivu: History WebPositive Window Historia Error opening downloads folder Download Window Virhe avattaessa latauskansiota Paste WebPositive Window Liitä +Proxy username: Settings Window Välityspalvelimen käyttäjätunnus: Settings Settings Window Asetukset %seconds seconds left Download Window %seconds sekuntia jäljellä Confirmation WebPositive Window Vahvistus @@ -41,6 +42,7 @@ Quit WebPositive Window Lopeta Full screen WebPositive Window Koko näyttö Open download error Download Window Avaa latausvirhe Standard font: Settings Window Vakiokirjasin: +Find previous occurrence of search terms WebPositive Window find bar previous button tooltip Etsi haettavien merkkijonojen edellinen esiintymä Restart Download Window Käynnistä uudelleen Proxy server Settings Window Välityspalvelin Open containing folder Download Window Avaa kansio, josta tiedosto löytyy @@ -58,6 +60,7 @@ Cut WebPositive Window Leikkaa Bookmark this page WebPositive Window Merkitse tämä sivu kirjanmerkillä There was an error trying to show the Bookmarks folder.\n\nError: %error WebPositive Window Don't translate variable %error Virhe yritettäessä näyttää kirjanmerkkikansiota.\n\nVirhe: %error Open downloads folder Download Window Avaa latauskansio +Proxy password: Settings Window Välityspalvelimen salasana: Number of days to keep links in History menu: Settings Window Kuinka monta päivää linkit pidetään historiavalikossa: Hide Download Window Piilota Reset size WebPositive Window Nollaa koko @@ -67,6 +70,7 @@ There was an error retrieving the bookmark folder.\n\nError: %error WebPositive Over 1 day left Download Window Yli 1 päivää jäljellä Downloads WebPositive Window Lataukset Requesting %url WebPositive Window Pyydetään %url +Find next occurrence of search terms WebPositive Window find bar next button tooltip Etsi haettavien merkkijonojen seuraava esiintymä Apply Settings Window Käytä Bookmark info WebPositive Window Kirjanmerkkitiedot Size: Font Selection view Koko: @@ -80,6 +84,7 @@ Open blank page Settings Window Avaa tyhjä sivu New tabs: Settings Window Uudet välilehdet: Cancel WebPositive Window Peru Open all WebPositive Window Avaa kaikki +Proxy server requires authentication Settings Window Välityspalvelin vaatii tunnistautumista Clear URL Bar Tyhjennä Cut URL Bar Leikkaa Clear WebPositive Window Tyhjennä diff --git a/data/catalogs/apps/webpositive/fr.catkeys b/data/catalogs/apps/webpositive/fr.catkeys index aa7643e2ec..979bd1f036 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 233049275 +1 french x-vnd.Haiku-WebPositive 3577331897 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 +Proxy username: Settings Window Nom d'utilisateur du serveur mandataire : Settings Settings Window Réglages %seconds seconds left Download Window %seconds secondes restantes Confirmation WebPositive Window Confirmation @@ -41,6 +42,7 @@ Quit WebPositive Window Quitter Full screen WebPositive Window Plein écran Open download error Download Window Erreur à l'ouverture du téléchargement Standard font: Settings Window Police standard : +Find previous occurrence of search terms WebPositive Window find bar previous button tooltip Rechercher la précédente occurrence de la chaîne Restart Download Window Recommencer Proxy server Settings Window Serveur mandataire Open containing folder Download Window Ouvrir le dossier contenant le fichier @@ -58,6 +60,7 @@ Cut WebPositive Window Couper Bookmark this page WebPositive Window Poser un signet sur cette page There was an error trying to show the Bookmarks folder.\n\nError: %error WebPositive Window Don't translate variable %error Une erreur est survenue essayant d'afficher le dossier des signets.\n\nErreur : %error Open downloads folder Download Window Ouvrir le dossier des téléchargements +Proxy password: Settings Window Mot de passe du serveur mandataire : Number of days to keep links in History menu: Settings Window Nombre de jours de conservation de l'historique : Hide Download Window Cacher Reset size WebPositive Window Réinitialiser la taille @@ -67,6 +70,7 @@ There was an error retrieving the bookmark folder.\n\nError: %error WebPositive Over 1 day left Download Window Plus d'un jour restant Downloads WebPositive Window Téléchargements Requesting %url WebPositive Window Requête de %url +Find next occurrence of search terms WebPositive Window find bar next button tooltip Rechercher la prochaine occurrence de la chaîne Apply Settings Window Appliquer Bookmark info WebPositive Window Informations sur le signet Size: Font Selection view Taille : @@ -80,6 +84,7 @@ Open blank page Settings Window Ouvrir une page blanche New tabs: Settings Window Nouvel onglet : Cancel WebPositive Window Annuler Open all WebPositive Window Tout ouvrir +Proxy server requires authentication Settings Window Le serveur mandataire requiert une authentification Clear URL Bar Vider Cut URL Bar Couper Clear WebPositive Window Vider diff --git a/data/catalogs/apps/webpositive/ru.catkeys b/data/catalogs/apps/webpositive/ru.catkeys index 6851f299d1..fd314dcbcc 100644 --- a/data/catalogs/apps/webpositive/ru.catkeys +++ b/data/catalogs/apps/webpositive/ru.catkeys @@ -11,7 +11,7 @@ Open location WebPositive Window Открыть адрес Clear history WebPositive Window Очистить историю WebPositive System name WebPositive Yesterday WebPositive Window Вчера -Default standard font size: Settings Window Размер стандартного шрифта по умолчанию: +Default standard font size: Settings Window Размер стандартного шрифта: Start page: Settings Window Начальная страница: History WebPositive Window История Error opening downloads folder Download Window Ошибка открытия каталога загрузок diff --git a/data/catalogs/apps/webpositive/zh_Hans.catkeys b/data/catalogs/apps/webpositive/zh_Hans.catkeys index 572d754276..4410a1d692 100644 --- a/data/catalogs/apps/webpositive/zh_Hans.catkeys +++ b/data/catalogs/apps/webpositive/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-WebPositive 233049275 +1 english x-vnd.Haiku-WebPositive 2633177086 Show home button Settings Window 显示 home 按钮 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 粘贴 +Proxy username: Settings Window 代理服务器 用户名: Settings Settings Window 设置 %seconds seconds left Download Window 剩余 %seconds 秒 Confirmation WebPositive Window 确认 @@ -58,6 +59,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 +69,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 +83,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/kits/fr.catkeys b/data/catalogs/kits/fr.catkeys index 7fc50b95cd..20c4b12e6b 100644 --- a/data/catalogs/kits/fr.catkeys +++ b/data/catalogs/kits/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-libbe 1916257017 +1 french x-vnd.Haiku-libbe 672385853 gamma AboutWindow gamma beta AboutWindow bêta %3.2f GiB StringForSize %3.2f Gio @@ -37,4 +37,5 @@ About %app… Dragger À propos de %app… development AboutWindow développement Error ZombieReplicantView Erreur Blue: ColorControl Bleu : +gold master AboutWindow finale Can't delete this replicant from its original application. Life goes on. Dragger Impossible de supprimer ce réplicant à partir de son application d'origine. La vie continue. diff --git a/data/catalogs/kits/tracker/fr.catkeys b/data/catalogs/kits/tracker/fr.catkeys index d34e810927..d1d68eb7ec 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 3375521561 +1 french x-vnd.Haiku-libtracker 4167158175 common B_COMMON_DIRECTORY commun OK WidgetAttributeText OK Icon view VolumeWindow Vue en icônes @@ -74,6 +74,7 @@ Arrange by ContainerWindow Trier par Mount server error AutoMounterSettings Erreur du serveur de montage Search FindPanel Chercher Preparing to empty Trash… StatusWindow Préparation au vidage de la Corbeille… +You cannot put the selected item(s) into the trash. FSUtils Vous ne pouvez pas déplacer l(es) élément(s) sélectionné(s) vers la corbeille. Disks Model Disques Create link ContainerWindow Créer un lien develop B_COMMON_DEVELOP_DIRECTORY développement diff --git a/data/catalogs/preferences/appearance/de.catkeys b/data/catalogs/preferences/appearance/de.catkeys index 0c016a73d8..0783140413 100644 --- a/data/catalogs/preferences/appearance/de.catkeys +++ b/data/catalogs/preferences/appearance/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-Appearance 76206318 +1 german x-vnd.Haiku-Appearance 2993758435 Plain font: Font view Normal: Control highlight Colors tab Steuerelement - Ausgewählt Control border Colors tab Steuerelement - Rahmen @@ -9,12 +9,14 @@ Defaults APRWindow Standardwerte Grayscale AntialiasingSettingsView Graustufen Shine Colors tab Glanz About DecorSettingsView Über +About decorator DecorSettingsView Dekorator Info Off AntialiasingSettingsView Aus Choose Decorator DecorSettingsView Dekorator wählen Success Colors tab Erfolg Inactive window tab text Colors tab Reiter - Text (inaktiv) Failure Colors tab Fehler Hinting menu AntialiasingSettingsView Hinting-Menü +Scroll bar: DecorSettingsView Scroll-Leiste: Document background Colors tab Dokument - Hintergrund Revert APRWindow Anfangswerte Window tab Colors tab Reiter @@ -34,6 +36,7 @@ List background Colors tab Liste - Hintergrund OK DecorSettingsView OK Control mark Colors tab Steuerelement - Markierung Size: Font Selection view Größe: +Decorator: DecorSettingsView Dekorator: Selected list item background Colors tab Liste - Hintergrund (ausgewählt) Panel background Colors tab Oberfläche - Hintergrund Menu font: Font view Menü: @@ -44,6 +47,7 @@ List item text Colors tab Liste - Text Appearance System name Erscheinungsbild Fixed font: Font view Feste Breite: 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. Franz jagt im total verwahrlosten Taxi quer durch Bayern. +%decorName\n\nAuthors:\n\t%decorAuthors\n\nURL: %decorURL\nLicense: %decorLic\n\n%decorDesc\n DecorSettingsView %decorName\n\nAutoren:\n\t%decorAuthors\n\nURL: %decorURL\nLizens: %decorLic\n\n%decorDesc\n Reduce colored edges filter strength: AntialiasingSettingsView Farbsaumfilter: 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 Zur Vermeidung von möglichen Patentproblemen ist die Kombination von Subpixel-Kantenglättung und Glyph-Hinting deaktiviert. Um diese Funktion zu aktivieren, müssen spezielle Optionen im Konfigurationsheader der Freetype-Bibliothek freigeschaltet und anschließend Haiku neu kompiliert werden. Control text Colors tab Steuerelement - Text diff --git a/data/catalogs/preferences/appearance/fi.catkeys b/data/catalogs/preferences/appearance/fi.catkeys index 453267d753..ffffc11545 100644 --- a/data/catalogs/preferences/appearance/fi.catkeys +++ b/data/catalogs/preferences/appearance/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-Appearance 76206318 +1 finnish x-vnd.Haiku-Appearance 2993758435 Plain font: Font view Pelkkä kirjasin: Control highlight Colors tab Kontrollin korostus Control border Colors tab Kontrollin reuna @@ -9,12 +9,14 @@ Defaults APRWindow Oletusasetukset Grayscale AntialiasingSettingsView Harmaasävy Shine Colors tab Hohto About DecorSettingsView Ohjelmasta +About decorator DecorSettingsView Koristeluohjelmasta Off AntialiasingSettingsView Pois päältä Choose Decorator DecorSettingsView Valitse koristelu Success Colors tab Onnistuminen Inactive window tab text Colors tab Epäaktiivisen ikkunavälilehden tekstin väri Failure Colors tab Epäonnistuminen Hinting menu AntialiasingSettingsView Vinkkausvalikko +Scroll bar: DecorSettingsView Vierityspalkki: Document background Colors tab Dokumentin tausta Revert APRWindow Palauta Window tab Colors tab Ikkunan välilehti @@ -34,6 +36,7 @@ List background Colors tab Luettelotausta OK DecorSettingsView Valmis Control mark Colors tab Ohjausmerkki Size: Font Selection view Koko: +Decorator: DecorSettingsView Koristelija: Selected list item background Colors tab Valitun luettelorivin tausta Panel background Colors tab Paneelin tausta Menu font: Font view Valikkokirjasin: @@ -44,6 +47,7 @@ List item text Colors tab Luettelorivin teksti Appearance System name Ulkoasuasetukset Fixed font: Font view Tasalevyinen kirjasin: 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. Albert osti fagotin ja töräytti puhkuvan melodian. +%decorName\n\nAuthors:\n\t%decorAuthors\n\nURL: %decorURL\nLicense: %decorLic\n\n%decorDesc\n DecorSettingsView %decorName\n\nTekijät:\n\t%decorAuthors\n\nVerkko-osoite: %decorURL\nLisenssi: %decorLic\n\n%decorDesc\n Reduce colored edges filter strength: AntialiasingSettingsView Vähennä värillisten reunojen suodatuksen vahvuutta: 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 Alipikselipohjainen reunanpehmennys yhdistettynä kirjoitusmerkkiviimeistelyyn ei ole saatavilla tässä Haiku-versiossa patenttisyiden takia. Ominaisuuden saaminen käyttöön vaatii Haikun uudelleenkääntämistä ja eräiden optioiden aktivoimista libfreetype:n määrittelytiedostoissa. Control text Colors tab Kontrollin teksti diff --git a/data/catalogs/preferences/appearance/fr.catkeys b/data/catalogs/preferences/appearance/fr.catkeys index 4bc08e816d..9ed06dc584 100644 --- a/data/catalogs/preferences/appearance/fr.catkeys +++ b/data/catalogs/preferences/appearance/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-Appearance 76206318 +1 french x-vnd.Haiku-Appearance 2993758435 Plain font: Font view Police simple : Control highlight Colors tab Mise en valeur de contrôle Control border Colors tab Bordure des contrôles @@ -9,12 +9,14 @@ Defaults APRWindow Défaut Grayscale AntialiasingSettingsView Niveaux de gris Shine Colors tab Lumière About DecorSettingsView À propos +About decorator DecorSettingsView À propos du décorateur Off AntialiasingSettingsView Désactivé Choose Decorator DecorSettingsView Choisir un décorateur Success Colors tab Réussite Inactive window tab text Colors tab Texte des titres de fenêtres inactives Failure Colors tab Échec Hinting menu AntialiasingSettingsView Menu ajustement +Scroll bar: DecorSettingsView Barre de défilement : Document background Colors tab Arrière plan du document Revert APRWindow Rétablir Window tab Colors tab Titre des fenêtres @@ -34,6 +36,7 @@ List background Colors tab Arrière-plan de la liste OK DecorSettingsView OK Control mark Colors tab Point de contrôle Size: Font Selection view Taille : +Decorator: DecorSettingsView Décorateur : Selected list item background Colors tab Arrière plan de l'élément sélectionnée dans la liste Panel background Colors tab Arrière plan des panneaux Menu font: Font view Police des menus : @@ -44,6 +47,7 @@ List item text Colors tab Texte de l’élément de la liste Appearance System name Apparence Fixed font: Font view Police à chasse fixe : 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. Voix ambiguë d'un cœur qui au zéphyr préfère les jattes de kiwis . 0123456789 +%decorName\n\nAuthors:\n\t%decorAuthors\n\nURL: %decorURL\nLicense: %decorLic\n\n%decorDesc\n DecorSettingsView %decorName\n\nAuteurs :\n\t%decorAuthors\n\nURL : %decorURL\nLicence : %decorLic\n\n%decorDesc\n Reduce colored edges filter strength: AntialiasingSettingsView Intensité du filtre de réduction des bords de couleurs : 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 Le lissage sous-pixel n'est pas disponible en même temps que les consignes de glyphes dans cette version d'Haiku afin d'éviter des problèmes de brevets logiciels. Pour activer cette fonctionnalité, vous devez compiler Haiku vous-même et activer certaines options dans l'en-tête de configuration de libfreetype. Control text Colors tab Texte des contrôles diff --git a/data/catalogs/preferences/appearance/hu.catkeys b/data/catalogs/preferences/appearance/hu.catkeys index 5d86de71e1..27ec888d17 100644 --- a/data/catalogs/preferences/appearance/hu.catkeys +++ b/data/catalogs/preferences/appearance/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Haiku-Appearance 1457181689 +1 hungarian x-vnd.Haiku-Appearance 727801787 Plain font: Font view Alap betűtípus: Control highlight Colors tab Kiválasztott vezérlőelem Control border Colors tab Vezérlőelem kerete @@ -16,6 +16,7 @@ Success Colors tab Sikerült Inactive window tab text Colors tab Inaktív ablak címszövege Failure Colors tab Nem sikerült Hinting menu AntialiasingSettingsView Körvonalmenü +Scroll bar: DecorSettingsView Görgetősáv: Document background Colors tab Dokumentum háttere Revert APRWindow Visszaállít Window tab Colors tab Ablakfül @@ -49,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\nKészítette:\n\t%decorAuthors\n\nURL: %decorURL\nLicense: %decorLic\n\n%decorDesc\n Reduce colored edges filter strength: AntialiasingSettingsView A színezett betűszélek szűrőjének erősségi szintje: 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 A betűkép-körvonalasítással összevont szubpixel-alapú élsimítás nem használható a Haiku ezen kiadásában, mivel lehetséges szabadalmi viták forrása lehet. E funckió használatához magának kell megépítenie saját Haiku-rendszerét és beállítania bizonyos opciókat a libfreetype konfigurációs fejlécében. +Scroll bar thumb Colors tab Görgetősáv megjelenése Control text Colors tab Vezérlőelem szövege Single: DecorSettingsView Egyszeres: Tooltip text Colors tab Buboréksúgó szövege diff --git a/data/catalogs/preferences/appearance/ja.catkeys b/data/catalogs/preferences/appearance/ja.catkeys index e2e9aa3a7f..bb8de888cd 100644 --- a/data/catalogs/preferences/appearance/ja.catkeys +++ b/data/catalogs/preferences/appearance/ja.catkeys @@ -1,4 +1,4 @@ -1 japanese x-vnd.Haiku-Appearance 1457181689 +1 japanese x-vnd.Haiku-Appearance 727801787 Plain font: Font view 標準フォント: Control highlight Colors tab コントロールのハイライト Control border Colors tab コントロールの境界 @@ -16,6 +16,7 @@ Success Colors tab 成功 Inactive window tab text Colors tab 非アクティブウィンドウタブの文字 Failure Colors tab 失敗 Hinting menu AntialiasingSettingsView ヒンティングメニュー +Scroll bar: DecorSettingsView スクロールバー: Document background Colors tab ドキュメントの背景 Revert APRWindow 元に戻す Window tab Colors tab ウィンドウのタブ @@ -49,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/appearance/pl.catkeys b/data/catalogs/preferences/appearance/pl.catkeys index 4023746798..ecf1e73628 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 1082331497 +1 polish x-vnd.Haiku-Appearance 2464466870 Plain font: Font view Zwykła czcionka: Control highlight Colors tab Podkreślenie kontrolki Control border Colors tab Obramowanie kontrolki @@ -9,12 +9,14 @@ Defaults APRWindow Ustaw domyślne Grayscale AntialiasingSettingsView Skala odcieni szarości Shine Colors tab Połysk About DecorSettingsView O +About decorator DecorSettingsView O dekoratorze Off AntialiasingSettingsView Wyłącz Choose Decorator DecorSettingsView Wybierz Dekorator Success Colors tab Sukces Inactive window tab text Colors tab Tekst nieaktywnej zakładki okna Failure Colors tab Niepowodzenie Hinting menu AntialiasingSettingsView Menu hintingu +Scroll bar: DecorSettingsView Pasek przewijania: Document background Colors tab Tło dokumentu Revert APRWindow Przywróć ustawienia Window tab Colors tab Zakładka okna @@ -24,6 +26,7 @@ Antialiasing APRWindow Antyaliasing Navigation base Colors tab Nawigacja Selected list item text Colors tab Tekst zaznaczonego elementu listy Window border Colors tab Obramowanie okna +Double: DecorSettingsView Podwójne: Window tab text Colors tab Tekst zakładki okna Document text Colors tab Tekst dokumentu Navigation pulse Colors tab Puls nawigacji @@ -43,6 +46,7 @@ The quick brown fox jumps over the lazy dog. Font Selection view Don't translate Reduce colored edges filter strength: AntialiasingSettingsView Zmniejszenie siły kolorowych filtrów krawędzi: 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 Antyaliasing podpikselowy w połączeniu z hintowaniem czcionek jest niedostępny w tym buildzie Haiku w celu uniknięcia problemów patentowych. Aby włączyć tę funkcjonalność, musisz zbudować Haiku samemu i włączyć niektóre opcje w pliku nagłówkowym biblioteki libfreetype. Control text Colors tab Tekst kontrolki +Single: DecorSettingsView Pojedynczy: Tooltip text Colors tab Tekst podpowiedzi Bold font: Font view Czcionka pogrubiona: Inactive window border Colors tab Nieaktywne obramowanie okna diff --git a/data/catalogs/preferences/appearance/ru.catkeys b/data/catalogs/preferences/appearance/ru.catkeys index 332409cadd..1bb3f6ddbd 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 1457181689 +1 russian x-vnd.Haiku-Appearance 2993758435 Plain font: Font view Простой шрифт: Control highlight Colors tab Подсветка элемента Control border Colors tab Граница элемента @@ -16,6 +16,7 @@ Success Colors tab Успех Inactive window tab text Colors tab Текст заголовка неактивного окна Failure Colors tab Неудача Hinting menu AntialiasingSettingsView Корректировка (хинтинг) +Scroll bar: DecorSettingsView Полоса прокрутки: Document background Colors tab Фон документа Revert APRWindow Вернуть Window tab Colors tab Заголовок окна diff --git a/data/catalogs/preferences/appearance/sv.catkeys b/data/catalogs/preferences/appearance/sv.catkeys index 12fdf2e9d0..7db65f6639 100644 --- a/data/catalogs/preferences/appearance/sv.catkeys +++ b/data/catalogs/preferences/appearance/sv.catkeys @@ -1,4 +1,4 @@ -1 swedish x-vnd.Haiku-Appearance 1457181689 +1 swedish x-vnd.Haiku-Appearance 2993758435 Plain font: Font view Vanlig font: Control highlight Colors tab Framhävd kontroll Control border Colors tab Kontrollkant @@ -16,6 +16,7 @@ Success Colors tab Framgång Inactive window tab text Colors tab Fliktext för inaktiva fönster Failure Colors tab Misslyckande Hinting menu AntialiasingSettingsView Betoningsmeny +Scroll bar: DecorSettingsView Rullningslist: Document background Colors tab Dokument bakgrund Revert APRWindow Återgå Window tab Colors tab Fösterflik diff --git a/data/catalogs/preferences/bluetooth/de.catkeys b/data/catalogs/preferences/bluetooth/de.catkeys index 66eee460a4..405b657daa 100644 --- a/data/catalogs/preferences/bluetooth/de.catkeys +++ b/data/catalogs/preferences/bluetooth/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-BluetoothPrefs 1628593228 +1 german x-vnd.Haiku-BluetoothPrefs 3212620536 About Bluetooth… Window Über Bluetooth… Handheld Settings view Handheld Default inquiry time: Settings view Suchdauer: @@ -55,6 +55,7 @@ Always ask Settings view Immer fragen Retrieving name of %1 Inquiry panel Name für %1 wird abgerufen Check that the Bluetooth capabilities of your remote device are activated. Press 'Inquiry' to start scanning. The needed time for the retrieval of the names is unknown, although should not take more than 3 seconds per device. Afterwards you will be able to add them to your main list, where you will be able to pair with them. Inquiry panel Bitte stellen Sie sicher, dass Bluetooth auf dem gesuchten Gerät aktiviert ist.\nDrücken Sie Suchen um andere Bluetooth-Geräte zu finden.\nFür gewöhnlich dauert das Ermitteln des Namens pro Gerät 3 Sekunden. Gefundene Bluetooth-Geräte können anschließend der Geräteliste hinzugefügt werden.\nWechseln Sie zur Liste der bekannten Geräte, wenn Sie eine Verbindung herstellen möchten. Authenticate Extended local device view Authentifizieren +Pick device... Settings view Gerät wählen... Retrieving names... Inquiry panel Empfangen der Namen... Help Window Hilfe Add… Remote devices Hinzu… diff --git a/data/catalogs/preferences/bluetooth/fi.catkeys b/data/catalogs/preferences/bluetooth/fi.catkeys index 55606a87a3..25babf8a78 100644 --- a/data/catalogs/preferences/bluetooth/fi.catkeys +++ b/data/catalogs/preferences/bluetooth/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-BluetoothPrefs 1628593228 +1 finnish x-vnd.Haiku-BluetoothPrefs 3212620536 About Bluetooth… Window Bluetooth-ohjelmasta… Handheld Settings view Kädessäpidettävät Default inquiry time: Settings view Oletuskyselyn pituus: @@ -55,6 +55,7 @@ Always ask Settings view Kysy joka kerta Retrieving name of %1 Inquiry panel Noudetaan %1-nimi Check that the Bluetooth capabilities of your remote device are activated. Press 'Inquiry' to start scanning. The needed time for the retrieval of the names is unknown, although should not take more than 3 seconds per device. Afterwards you will be able to add them to your main list, where you will be able to pair with them. Inquiry panel Tarkista, että etälaitteen bluetoothominaisuudet on aktivoitu. Paina ’Kysely’ käynnistääksesi haun. Nimien noutoon tarvittavan ajan määrä ei ole tiedossa, mutta sen ei pitäisi viedä yli 3 sekuntia per laite. Myöhemmin voit lisätä ne päälistaasi, jossa pystyt yhdistämään ne. Authenticate Extended local device view Todenna +Pick device... Settings view Valitse laite... Retrieving names... Inquiry panel Noudetaan nimiä... Help Window Opaste Add… Remote devices Lisää… diff --git a/data/catalogs/preferences/bluetooth/fr.catkeys b/data/catalogs/preferences/bluetooth/fr.catkeys index 02ab0c5ab2..f8b9276d1e 100644 --- a/data/catalogs/preferences/bluetooth/fr.catkeys +++ b/data/catalogs/preferences/bluetooth/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-BluetoothPrefs 1628593228 +1 french x-vnd.Haiku-BluetoothPrefs 3212620536 About Bluetooth… Window À propos de Bluetooth… Handheld Settings view Appareil de poche Default inquiry time: Settings view Temps de requête par défaut : @@ -55,6 +55,7 @@ Always ask Settings view Toujours demander Retrieving name of %1 Inquiry panel Récupérer le nom de %1 Check that the Bluetooth capabilities of your remote device are activated. Press 'Inquiry' to start scanning. The needed time for the retrieval of the names is unknown, although should not take more than 3 seconds per device. Afterwards you will be able to add them to your main list, where you will be able to pair with them. Inquiry panel Vérifiez que les fonctionnalités Bluetooth de votre appareil distant soient activées. Appuyez sur « Examiner » pour lancer la recherche. Le temps nécessaire pour récupérer les noms n'est pas connu, mais ça ne devrait pas prendre plus de 3 secondes par appareil. Ensuite, vous pourrez les ajouter à la liste principale, où vous pourrez vous associer avec eux. Authenticate Extended local device view Authentification +Pick device... Settings view Choisir un périphérique... Retrieving names... Inquiry panel Récupération des noms… Help Window Aide Add… Remote devices Ajouter… diff --git a/data/catalogs/preferences/network/fi.catkeys b/data/catalogs/preferences/network/fi.catkeys index 52d2f96779..76bd3733ee 100644 --- a/data/catalogs/preferences/network/fi.catkeys +++ b/data/catalogs/preferences/network/fi.catkeys @@ -1,22 +1,27 @@ -1 finnish x-vnd.Haiku-Network 365183238 +1 finnish x-vnd.Haiku-Network 1341378870 Choose automatically EthernetSettingsView Valitse automaattisesti Gateway: EthernetSettingsView Yhdyskäytävä: Netmask: EthernetSettingsView Verkkopeite: DHCP EthernetSettingsView DHCP DNS #2: EthernetSettingsView DNS nr2: Apply EthernetSettingsView Käytä +Netmask is invalid EthernetSettingsView Verkkopeite on virheellinen OK EthernetSettingsView Valmis DNS #1: EthernetSettingsView DNS nr1: IP address: EthernetSettingsView IP-osoite: Adapter: EthernetSettingsView Adapteri: Domain: EthernetSettingsView Verkkoalue: +Gateway is invalid EthernetSettingsView Yhdyskäytävä on virheellinen +DNS #1 is invalid EthernetSettingsView DNS nro 1 on virheellinen Revert EthernetSettingsView Palauta EthernetSettingsView Network System name Verkkotila-asetukset Mode: EthernetSettingsView Tila: +IP address is invalid EthernetSettingsView IP-osoite on virheellinen Network: EthernetSettingsView Verkko: The net_server needs to run for the auto configuration! EthernetSettingsView Automaattiasetusta varten net_server on suoritettava! Disabled EthernetSettingsView Ota pois käytöstä Auto-configuring failed: EthernetSettingsView Automaattiasetus epäonnistui: Static EthernetSettingsView Staattinen +DNS #2 is invalid EthernetSettingsView DNS nro 2 on virheellinen EthernetSettingsView diff --git a/data/catalogs/preferences/network/fr.catkeys b/data/catalogs/preferences/network/fr.catkeys index fad450991c..5fe3eadd5c 100644 --- a/data/catalogs/preferences/network/fr.catkeys +++ b/data/catalogs/preferences/network/fr.catkeys @@ -1,22 +1,27 @@ -1 french x-vnd.Haiku-Network 365183238 +1 french x-vnd.Haiku-Network 1341378870 Choose automatically EthernetSettingsView Choisir automatiquement Gateway: EthernetSettingsView Passerelle : Netmask: EthernetSettingsView Masque réseau : DHCP EthernetSettingsView DHCP DNS #2: EthernetSettingsView DNS n°2 : Apply EthernetSettingsView Appliquer +Netmask is invalid EthernetSettingsView Le masque réseau est invalide OK EthernetSettingsView OK DNS #1: EthernetSettingsView DNS n°1 : IP address: EthernetSettingsView Adresse IP : Adapter: EthernetSettingsView Adaptateur : Domain: EthernetSettingsView Domaine : +Gateway is invalid EthernetSettingsView La passerelle est invalide +DNS #1 is invalid EthernetSettingsView Le DNS n°1 est invalide Revert EthernetSettingsView Rétablir EthernetSettingsView Network System name Réseau Mode: EthernetSettingsView Mode : +IP address is invalid EthernetSettingsView L'adresse IP est invalide Network: EthernetSettingsView Réseau : The net_server needs to run for the auto configuration! EthernetSettingsView Le net_server doit être lancé pour la configuration automatique ! Disabled EthernetSettingsView Désactivé Auto-configuring failed: EthernetSettingsView Échec de la configuration automatique : Static EthernetSettingsView Statique +DNS #2 is invalid EthernetSettingsView Le DNS n°2 est invalide EthernetSettingsView diff --git a/data/catalogs/preferences/notifications/fr.catkeys b/data/catalogs/preferences/notifications/fr.catkeys index c8e4609f80..00c196bf7f 100644 --- a/data/catalogs/preferences/notifications/fr.catkeys +++ b/data/catalogs/preferences/notifications/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-Notifications 814394708 +1 french x-vnd.Haiku-Notifications 2177286129 An error occurred saving the preferences.\nIt's possible you are running out of disk space. GeneralView Une erreur est survenue lors de la sauvegarde des préférences.\nVous n'avez peut-être plus suffisamment d'espace libre sur votre disque. Notifications GeneralView Notifications seconds of inactivity GeneralView secondes d'inactivités @@ -17,6 +17,7 @@ Cannot disable notifications because the server can't be reached. GeneralView I Progress NotificationView Progression Last Received NotificationView Dernière reçue General PrefletView Général +Apply PrefletWin Appliquer Display PrefletView Affichage Can't enable notifications at startup time, you probably don't have write permission to the boot settings directory. GeneralView Impossible d'activer les notifications au démarrage. Vous n'avez probablement pas le droit d'écrire dans le répertoire des réglages du démarrage. Search: NotificationView Rechercher : diff --git a/data/catalogs/preferences/printers/pl.catkeys b/data/catalogs/preferences/printers/pl.catkeys index 1d82789c7d..88ce293236 100644 --- a/data/catalogs/preferences/printers/pl.catkeys +++ b/data/catalogs/preferences/printers/pl.catkeys @@ -10,7 +10,7 @@ Add printer AddPrinterDialog Dodaj drukarkę Green TestPageView Zielony Printers PrintersWindow Drukarki Default Printer PrinterListView Domyślna drukarka -Transport: %transport% %transport_address% PrinterListView Transport: %transport% %transport_address% +Transport: %transport% %transport_address% PrinterListView Podsystem transportu: %transport%, adres: %transport_address% No pending jobs. PrinterListView Brak oczekujących zadań. pages JobListView strony Printers System name Drukarki @@ -23,13 +23,13 @@ Black TestPageView Czarny Restart job PrintersWindow Zrestartuj zadanie Add AddPrinterDialog Dodaj Make default PrintersWindow Ustaw jako domyślną drukarkę -Transport: %transport% %transport_address% TestPageView Transport: %transport%, adres: %transport_address% +Transport: %transport% %transport_address% TestPageView Podsystem transportu: %transport%, adres: %transport_address% Cancel job PrintersWindow Anuluj zadanie Yellow TestPageView Żółty Blue TestPageView Niebieski 1 pending job. PrinterListView 1 zadanie w toku. Remove PrintersWindow Usuń - AddPrinterDialog + AddPrinterDialog Add … PrintersWindow Dodaj … Print jobs for PrintersWindow Drukowanie dla Failed JobListView Nie wykonano diff --git a/data/catalogs/preferences/time/fr.catkeys b/data/catalogs/preferences/time/fr.catkeys index 0fc73b0f3a..504ee86225 100644 --- a/data/catalogs/preferences/time/fr.catkeys +++ b/data/catalogs/preferences/time/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-Time 3544635877 +1 french x-vnd.Haiku-Time 3259467657 GMT (UNIX compatible) Time GMT (compatible UNIX) OK Time OK Asia Time Asie @@ -11,6 +11,7 @@ Preview time: Time Aperçu de l'heure : Synchronize Time Synchroniser Revert Time Rétablir Pacific Time Pacifique +Show day of week Time Afficher le jour de la semaine Add Time Ajouter Date and time Time Date et heure about Time À propos @@ -26,6 +27,7 @@ Time Time Heure Indian Time Indien Sending request failed Time L'envoi d'une requête a échoué Arctic Time Arctique +Display time with seconds Time Afficher l'heure avec les secondes Time System name Heure America Time Amérique Reset Time Réinitialiser @@ -33,6 +35,8 @@ Synchronize at boot Time Synchroniser au démarrage Time & Date, written by:\n\n\tAndrew Edward McCall\n\tMike Berg\n\tJulun\n\tPhilippe Saint-Pierre\n\nCopyright 2004-2012, Haiku. Time Date & Heure, écrit par :\n\n\tAndrew Edward McCall\n\tMike Berg\n\tJulun\n\tPhilippe Saint-Pierre\n\nCopyright 2004-2012, Haiku. Received invalid time Time Une heure non valide a été reçue Antarctica Time Antarctique +Show time zone Time Afficher le fuseau horaire +Show clock in Deskbar Time Afficher l'heure dans la Deskbar The following error occured while synchronizing:r\n%s: %s Time L'erreur suivante est survenue lors de la synchronisation :\n%s : %s Time Current time: Time Heure actuelle : diff --git a/data/catalogs/servers/print/de.catkeys b/data/catalogs/servers/print/de.catkeys index 6410fd027e..14e708c942 100644 --- a/data/catalogs/servers/print/de.catkeys +++ b/data/catalogs/servers/print/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Be-PSRV 1761631281 +1 german x-vnd.Be-PSRV 123334776 Undefined ConfigWindow Unbestimmt Return the number of available transports PrintServerApp Scripting Anzahl der verfügbaren Transporte melden Return the number of available printers PrintServerApp Scripting Meldet die Anzahl der verfügbaren Drucker @@ -9,6 +9,7 @@ Retrieve a specific printer PrintServerApp Scripting Einen bestimmten Drucker h Page %1 to %2 ConfigWindow Seite %1 bis %2 Get name of the printer add-on used for this printer Printer Scripting Name des von diesem Drucker verwendeten Add-ons anzeigen Page setup: ConfigWindow Seite einrichten: +B5 (JIS) ConfigWindow JIS P0138 B5, a Japanese paper size B5 (JIS) OK ConfigWindow OK Cancel ConfigWindow Abbrechen Printer server ConfigWindow Druckserver diff --git a/data/catalogs/servers/print/fi.catkeys b/data/catalogs/servers/print/fi.catkeys index 3c6507dc93..ca359a1b9e 100644 --- a/data/catalogs/servers/print/fi.catkeys +++ b/data/catalogs/servers/print/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Be-PSRV 1761631281 +1 finnish x-vnd.Be-PSRV 123334776 Undefined ConfigWindow Määrittelemätön Return the number of available transports PrintServerApp Scripting Palauta käytettävissä olevien siirtojen lukumäärä Return the number of available printers PrintServerApp Scripting Palauta käytettävissä olevien tulostimien lukumäärä @@ -9,6 +9,7 @@ Retrieve a specific printer PrintServerApp Scripting Nouda tietty tulostin Page %1 to %2 ConfigWindow Sivu %1 ... %2 Get name of the printer add-on used for this printer Printer Scripting Hae tämän tulostimen käyttämän tulostinlisäosan nimi Page setup: ConfigWindow Sivuasetus: +B5 (JIS) ConfigWindow JIS P0138 B5, a Japanese paper size B5 (JIS) OK ConfigWindow Valmis Cancel ConfigWindow Peru Printer server ConfigWindow Tulostinpalvelin diff --git a/data/catalogs/servers/print/fr.catkeys b/data/catalogs/servers/print/fr.catkeys index acf7fad19c..18287e87f6 100644 --- a/data/catalogs/servers/print/fr.catkeys +++ b/data/catalogs/servers/print/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Be-PSRV 1761631281 +1 french x-vnd.Be-PSRV 123334776 Undefined ConfigWindow Indéfini Return the number of available transports PrintServerApp Scripting Renvoyer le nombre de liaisons disponibles Return the number of available printers PrintServerApp Scripting Renvoyer le nombre d'imprimante disponible @@ -9,6 +9,7 @@ Retrieve a specific printer PrintServerApp Scripting Récupérer une imprimante Page %1 to %2 ConfigWindow Page %1 sur %2 Get name of the printer add-on used for this printer Printer Scripting Obtenir le nom de l'extension d'impression utilisée pour cette imprimante Page setup: ConfigWindow Réglages de page : +B5 (JIS) ConfigWindow JIS P0138 B5, a Japanese paper size B5 (JIS) OK ConfigWindow OK Cancel ConfigWindow Annuler Printer server ConfigWindow Serveur d'impression diff --git a/data/catalogs/servers/print/hu.catkeys b/data/catalogs/servers/print/hu.catkeys index 84ecac8b95..0647329976 100644 --- a/data/catalogs/servers/print/hu.catkeys +++ b/data/catalogs/servers/print/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Be-PSRV 1761631281 +1 hungarian x-vnd.Be-PSRV 123334776 Undefined ConfigWindow Nem meghatározott Return the number of available transports PrintServerApp Scripting Megadja az elérhető transzporterek számát Return the number of available printers PrintServerApp Scripting Megadja az elérhető nyomtatók számát @@ -9,6 +9,7 @@ Retrieve a specific printer PrintServerApp Scripting Megad egy válaszott nyomt Page %1 to %2 ConfigWindow %1 - %2 oldal Get name of the printer add-on used for this printer Printer Scripting Megadja a nyomtatón használt nyomtatóbővítményt Page setup: ConfigWindow Oldalbeállítás: +B5 (JIS) ConfigWindow JIS P0138 B5, a Japanese paper size B5 (JIS) OK ConfigWindow Rendben Cancel ConfigWindow Mégse Printer server ConfigWindow Nyomtatókiszolgáló diff --git a/data/catalogs/servers/print/ja.catkeys b/data/catalogs/servers/print/ja.catkeys index 69a48912c1..ba7b94ada7 100644 --- a/data/catalogs/servers/print/ja.catkeys +++ b/data/catalogs/servers/print/ja.catkeys @@ -1,4 +1,4 @@ -1 japanese x-vnd.Be-PSRV 1761631281 +1 japanese x-vnd.Be-PSRV 123334776 Undefined ConfigWindow 未定義 Return the number of available transports PrintServerApp Scripting トランスポートの数を取得 Return the number of available printers PrintServerApp Scripting プリンターの数を取得 @@ -9,6 +9,7 @@ Retrieve a specific printer PrintServerApp Scripting 特定のプリンター Page %1 to %2 ConfigWindow ページ %1 からページ %2 まで Get name of the printer add-on used for this printer Printer Scripting このプリンターが使うプリンターアドオンを取得 Page setup: ConfigWindow ページ設定: +B5 (JIS) ConfigWindow JIS P0138 B5, a Japanese paper size JIS B5 (182 x 257 mm) OK ConfigWindow OK Cancel ConfigWindow 中止 Printer server ConfigWindow プリンターサーバー @@ -21,7 +22,7 @@ A6 ConfigWindow ISO 216 paper size A6 (105 x 148 mm) Portrait ConfigWindow 縦 All pages ConfigWindow 全ページ There is no default printer set up. PrintServerApp デフォルトプリンターが設定されていません。 -B5 ConfigWindow ISO 216 paper size ISO B5 (176 x 250 mm) +B5 ConfigWindow ISO 216 paper size B5 (176 x 250 mm) A0 ConfigWindow ISO 216 paper size A0 (841 x 1189 mm) Letter ConfigWindow ANSI A (letter), a North American paper size Letter (216 x 279 mm) Printer: ConfigWindow プリンター: diff --git a/data/catalogs/servers/print/ru.catkeys b/data/catalogs/servers/print/ru.catkeys index 461e7dd8b8..e5ab7dc274 100644 --- a/data/catalogs/servers/print/ru.catkeys +++ b/data/catalogs/servers/print/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Be-PSRV 1761631281 +1 russian x-vnd.Be-PSRV 123334776 Undefined ConfigWindow не определены Return the number of available transports PrintServerApp Scripting Возвращает количество доступных транспортов Return the number of available printers PrintServerApp Scripting Возвращает количество доступных принтеров @@ -9,6 +9,7 @@ Retrieve a specific printer PrintServerApp Scripting Запросить ука Page %1 to %2 ConfigWindow Страница %1 из %2 Get name of the printer add-on used for this printer Printer Scripting Получить имя дополнения принтера, используемого для этого принтера Page setup: ConfigWindow Настройки печати: +B5 (JIS) ConfigWindow JIS P0138 B5, a Japanese paper size B5 (JIS) OK ConfigWindow ОК Cancel ConfigWindow Отмена Printer server ConfigWindow Сервер печати diff --git a/data/catalogs/servers/print/sv.catkeys b/data/catalogs/servers/print/sv.catkeys index d9eeade09e..dde0ebffe0 100644 --- a/data/catalogs/servers/print/sv.catkeys +++ b/data/catalogs/servers/print/sv.catkeys @@ -1,4 +1,4 @@ -1 swedish x-vnd.Be-PSRV 1761631281 +1 swedish x-vnd.Be-PSRV 123334776 Undefined ConfigWindow Odefinierad Return the number of available transports PrintServerApp Scripting Visa antalet tillgängliga åtkomstmetoder Return the number of available printers PrintServerApp Scripting Visa antal tillgängliga skrivare @@ -9,6 +9,7 @@ Retrieve a specific printer PrintServerApp Scripting Visa en specifik skrivare Page %1 to %2 ConfigWindow Sida %1 till %2 Get name of the printer add-on used for this printer Printer Scripting Visa namnet till skrivartillägget för denna skrivare Page setup: ConfigWindow Sidinställningar: +B5 (JIS) ConfigWindow JIS P0138 B5, a Japanese paper size B5 (JIS) OK ConfigWindow OK Cancel ConfigWindow Avbryt Printer server ConfigWindow Utskriftsserver diff --git a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/de.catkeys b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/de.catkeys new file mode 100644 index 0000000000..e117b322ed --- /dev/null +++ b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/de.catkeys @@ -0,0 +1,33 @@ +1 german x-vnd.Haiku-InterfacesAddOn 160108912 +Interface InterfaceWindow Interface +Configure… InterfacesListView Konfiguriere… +Static IntefaceAddressView Statisch +None InterfacesListView Keine +IP: InterfacesListView IPv4 address label IP: +Status: IntefaceHardwareView Status: +IPv6: InterfacesListView IPv6 address label IPv6: +Save InterfaceWindow Speichern +Link speed: IntefaceHardwareView Geschwindigkeit: +Renegotiate InterfacesAddOn Neu verhandeln +The method for obtaining an IP address IntefaceAddressView Die Art eine IP Adresse zu erhalten +Your gateway IntefaceAddressView Das Gateway +Enable InterfacesListView Aktivieren +Received: IntefaceHardwareView Empfangen: +Revert InterfaceWindow Anfangswerte +connected IntefaceHardwareView verbunden +Gateway: IntefaceAddressView Gateway: +Disable InterfacesListView Deaktivieren +Sent: IntefaceHardwareView Gesendet: +Disable InterfacesAddOn Deaktivieren +Configure… InterfacesAddOn Konfiguriere... +Renegotiate Address InterfacesListView Adresse neu verhandeln +DHCP IntefaceAddressView DHCP +Mode: IntefaceAddressView Modus: +Your netmask IntefaceAddressView Netzmaske +IP Address: IntefaceAddressView IP Adresse: +Off IntefaceAddressView Aus +MAC address: IntefaceHardwareView MAC Adresse: +Netmask: IntefaceAddressView Netzmaske: +Your IP address IntefaceAddressView IP Adresse +%llu KBytes IntefaceHardwareView %llu KByte +disconnected IntefaceHardwareView getrennt diff --git a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/fi.catkeys b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/fi.catkeys new file mode 100644 index 0000000000..116f6bb43e --- /dev/null +++ b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/fi.catkeys @@ -0,0 +1,29 @@ +1 finnish x-vnd.Haiku-InterfacesAddOn 1172292901 +Configure… InterfacesListView Aseta… +Static IntefaceAddressView Staattinen +None InterfacesListView Ei mitään +IP: InterfacesListView IPv4 address label IP: +Status: IntefaceHardwareView Tila: +IPv6: InterfacesListView IPv6 address label IPv6: +Save InterfaceWindow Tallenna +Link speed: IntefaceHardwareView Yhteysnopeus: +Renegotiate InterfacesAddOn Neuvottele uudelleen +The method for obtaining an IP address IntefaceAddressView IP-osoitteen hakumenetelmä +Your gateway IntefaceAddressView Yhdyskäytäväsi +Enable InterfacesListView Käytössä +Revert InterfaceWindow Palauta +connected IntefaceHardwareView yhdistetty +Gateway: IntefaceAddressView Yhdyskäytävä: +Disable InterfacesListView Ei ole käytössä +Disable InterfacesAddOn Ei ole käytössä +Configure… InterfacesAddOn Aseta… +Renegotiate Address InterfacesListView Neuvottele osoite uudelleen +DHCP IntefaceAddressView DHCP +Mode: IntefaceAddressView Tila: +Your netmask IntefaceAddressView Verkopeitteesi +IP Address: IntefaceAddressView IP-osoite: +Off IntefaceAddressView Pois käytöstä +MAC address: IntefaceHardwareView MAC-osoite: +Netmask: IntefaceAddressView Verkkopeite: +Your IP address IntefaceAddressView IP-osoitteesi +disconnected IntefaceHardwareView yhteys katkaistu diff --git a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/hu.catkeys b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/hu.catkeys new file mode 100644 index 0000000000..8a05536b91 --- /dev/null +++ b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/hu.catkeys @@ -0,0 +1,33 @@ +1 hungarian x-vnd.Haiku-InterfacesAddOn 160108912 +Interface InterfaceWindow Eszköz +Configure… InterfacesListView Beállítás… +Static IntefaceAddressView Állandó +None InterfacesListView Nincs +IP: InterfacesListView IPv4 address label IP: +Status: IntefaceHardwareView Állapot: +IPv6: InterfacesListView IPv6 address label IPv6: +Save InterfaceWindow Mentés +Link speed: IntefaceHardwareView Kapcsolat sebessége: +Renegotiate InterfacesAddOn Megújítás +The method for obtaining an IP address IntefaceAddressView Az IP-cím lekérésének módja +Your gateway IntefaceAddressView Átjáró +Enable InterfacesListView Engedélyezés +Received: IntefaceHardwareView Fogadott: +Revert InterfaceWindow Visszaállítás +connected IntefaceHardwareView csatlakozva +Gateway: IntefaceAddressView Átjáró: +Disable InterfacesListView Letiltás +Sent: IntefaceHardwareView Küldött: +Disable InterfacesAddOn Letiltás +Configure… InterfacesAddOn Beállítás… +Renegotiate Address InterfacesListView Cím újra lekérése +DHCP IntefaceAddressView DHCP +Mode: IntefaceAddressView Mód: +Your netmask IntefaceAddressView Hálózati maszk +IP Address: IntefaceAddressView IP-cím: +Off IntefaceAddressView Kikapcsolva +MAC address: IntefaceHardwareView MAC-cím: +Netmask: IntefaceAddressView Hálózati maszk: +Your IP address IntefaceAddressView IP cím +%llu KBytes IntefaceHardwareView %llu KByte +disconnected IntefaceHardwareView leválasztva diff --git a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/ja.catkeys b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/ja.catkeys new file mode 100644 index 0000000000..e9c6038d9b --- /dev/null +++ b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/ja.catkeys @@ -0,0 +1,33 @@ +1 japanese 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 KBytes +disconnected IntefaceHardwareView 切断されました diff --git a/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/sv.catkeys b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/sv.catkeys new file mode 100644 index 0000000000..65d08d0d2e --- /dev/null +++ b/data/catalogs/tests/kits/net/preflet/InterfacesAddOn/sv.catkeys @@ -0,0 +1,29 @@ +1 swedish x-vnd.Haiku-InterfacesAddOn 1172292901 +Configure… InterfacesListView Konfigurera... +Static IntefaceAddressView Statisk +None InterfacesListView Ingen +IP: InterfacesListView IPv4 address label IP: +Status: IntefaceHardwareView Status: +IPv6: InterfacesListView IPv6 address label IPv6: +Save InterfaceWindow Spara +Link speed: IntefaceHardwareView Länkhastighet: +Renegotiate InterfacesAddOn Omförhandla +The method for obtaining an IP address IntefaceAddressView Metoden för att få en IP adress +Your gateway IntefaceAddressView Min gateway +Enable InterfacesListView Aktivera +Revert InterfaceWindow Återgå +connected IntefaceHardwareView ansluten +Gateway: IntefaceAddressView Gateway: +Disable InterfacesListView Inaktivera +Disable InterfacesAddOn Inaktivera +Configure… InterfacesAddOn Konfigurera… +Renegotiate Address InterfacesListView Omförhandla Adressen +DHCP IntefaceAddressView DHCP +Mode: IntefaceAddressView Läge: +Your netmask IntefaceAddressView Min nätmask +IP Address: IntefaceAddressView IP-adress: +Off IntefaceAddressView Av +MAC address: IntefaceHardwareView MAC-adress +Netmask: IntefaceAddressView Nätmask: +Your IP address IntefaceAddressView Din IP-adress +disconnected IntefaceHardwareView koppla från diff --git a/data/catalogs/tests/servers/app/playground/fr.catkeys b/data/catalogs/tests/servers/app/playground/fr.catkeys index c5e862594b..00386fee5c 100644 --- a/data/catalogs/tests/servers/app/playground/fr.catkeys +++ b/data/catalogs/tests/servers/app/playground/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-Playground 584609351 +1 french x-vnd.Haiku-Playground 1375574837 Line Playground Ligne Fill Playground Remplir Over Playground Dessus @@ -24,6 +24,7 @@ New object Playground Nouvel objet Test Playground Tester Max Playground Max Add Playground Ajouter +Playground System name Aire de jeu Erase Playground Effacer File Playground Fichier Subtract Playground Soustraire diff --git a/docs/user/drivers/fs_interface.dox b/docs/user/drivers/fs_interface.dox index ec891e1afa..edfe0573fe 100644 --- a/docs/user/drivers/fs_interface.dox +++ b/docs/user/drivers/fs_interface.dox @@ -325,8 +325,11 @@ Invoked by the VFS when it is asked to unmount the volume. The function must free all resources associated with the mounted volume, including the volume - handle. Although the mount() hook called publish_vnode() for the root node - of the volume, unmount() must not invoke put_vnode(). + handle. Before unmount() is called, the VFS calls + file_system_module_info::put_vnode() respectively + file_system_module_info::remove_vnode() for each of the volume's nodes. That + is although the mount() hook called publish_vnode() for the volume's root + node, unmount() must not invoke put_vnode(). \param volume The volume object. \return \c B_OK if everything went fine, another error code otherwise. The diff --git a/headers/os/interface/ControlLook.h b/headers/os/interface/ControlLook.h index 754c203023..1e1a5ca904 100644 --- a/headers/os/interface/ControlLook.h +++ b/headers/os/interface/ControlLook.h @@ -61,7 +61,11 @@ public: B_LEFT_ARROW = 0, B_RIGHT_ARROW = 1, B_UP_ARROW = 2, - B_DOWN_ARROW = 3 + B_DOWN_ARROW = 3, + B_LEFT_UP_ARROW = 4, + B_RIGHT_UP_ARROW = 5, + B_RIGHT_DOWN_ARROW = 6, + B_LEFT_DOWN_ARROW = 7 }; enum { diff --git a/headers/os/interface/InterfaceDefs.h b/headers/os/interface/InterfaceDefs.h index 51b5f6f25a..158eb3d7c4 100644 --- a/headers/os/interface/InterfaceDefs.h +++ b/headers/os/interface/InterfaceDefs.h @@ -311,6 +311,8 @@ enum color_which { B_LIST_ITEM_TEXT_COLOR = 30, B_LIST_SELECTED_ITEM_TEXT_COLOR = 31, + B_SCROLL_BAR_THUMB_COLOR = 32, + B_TOOL_TIP_BACKGROUND_COLOR = 20, B_TOOL_TIP_TEXT_COLOR = 21, @@ -329,9 +331,9 @@ enum color_which { B_KEYBOARD_NAVIGATION_COLOR = B_NAVIGATION_BASE_COLOR, B_MENU_SELECTION_BACKGROUND_COLOR = B_MENU_SELECTED_BACKGROUND_COLOR, - // These are deprecated -- do not use in new code. See BScreen for - // the replacement for B_DESKTOP_COLOR. + // The following constants are deprecated, do not use in new code. B_DESKTOP_COLOR = 5 + // see BScreen class for B_DESKTOP_COLOR replacement }; diff --git a/headers/os/interface/ListView.h b/headers/os/interface/ListView.h index bc3a6175f0..bca5b930be 100644 --- a/headers/os/interface/ListView.h +++ b/headers/os/interface/ListView.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009, Haiku, Inc. All rights reserved. + * Copyright 2002-2013 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _LIST_VIEW_H @@ -14,6 +14,7 @@ struct track_data; + enum list_view_type { B_SINGLE_SELECTION_LIST, B_MULTIPLE_SELECTION_LIST @@ -58,13 +59,13 @@ public: virtual void MessageReceived(BMessage* message); virtual void KeyDown(const char* bytes, int32 numBytes); virtual void MouseDown(BPoint where); - virtual void MouseUp(BPoint point); - virtual void MouseMoved(BPoint point, uint32 code, + virtual void MouseUp(BPoint where); + virtual void MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage); virtual void ResizeToPreferred(); - virtual void GetPreferredSize(float* _width, - float* _height); + virtual void GetPreferredSize(float *_width, + float *_height); virtual BSize MinSize(); virtual BSize MaxSize(); diff --git a/headers/os/interface/Menu.h b/headers/os/interface/Menu.h index 60ba113883..4ef27a77f5 100644 --- a/headers/os/interface/Menu.h +++ b/headers/os/interface/Menu.h @@ -214,7 +214,7 @@ private: bool moveItems, float* width, float* height); void _ComputeColumnLayout(int32 index, bool bestFit, - bool moveItems, BRect& outRect); + bool moveItems, BRect* override, BRect& outRect); void _ComputeRowLayout(int32 index, bool bestFit, bool moveItems, BRect& outRect); void _ComputeMatrixLayout(BRect& outRect); diff --git a/headers/os/kernel/OS.h b/headers/os/kernel/OS.h index 8532de03a9..dc91207136 100644 --- a/headers/os/kernel/OS.h +++ b/headers/os/kernel/OS.h @@ -73,11 +73,14 @@ typedef struct area_info { #define B_32_BIT_CONTIGUOUS 6 /* B_CONTIGUOUS, < 4 GB physical address */ /* address spec for create_area(), and clone_area() */ -#define B_ANY_ADDRESS 0 -#define B_EXACT_ADDRESS 1 -#define B_BASE_ADDRESS 2 -#define B_CLONE_ADDRESS 3 -#define B_ANY_KERNEL_ADDRESS 4 +#define B_ANY_ADDRESS 0 +#define B_EXACT_ADDRESS 1 +#define B_BASE_ADDRESS 2 +#define B_CLONE_ADDRESS 3 +#define B_ANY_KERNEL_ADDRESS 4 +/* B_ANY_KERNEL_BLOCK_ADDRESS 5 */ +#define B_RANDOMIZED_ANY_ADDRESS 6 +#define B_RANDOMIZED_BASE_ADDRESS 7 /* area protection */ #define B_READ_AREA 1 diff --git a/headers/os/locale/UnicodeChar.h b/headers/os/locale/UnicodeChar.h index d902a79c23..3031866aaf 100644 --- a/headers/os/locale/UnicodeChar.h +++ b/headers/os/locale/UnicodeChar.h @@ -8,6 +8,7 @@ enum unicode_char_category // Non-category for unassigned and non-character code points. B_UNICODE_UNASSIGNED = 0, + B_UNICODE_GENERAL_OTHER_TYPES = 0, // Cn B_UNICODE_UPPERCASE_LETTER = 1, // Lu B_UNICODE_LOWERCASE_LETTER = 2, // Ll B_UNICODE_TITLECASE_LETTER = 3, // Lt @@ -37,152 +38,289 @@ enum unicode_char_category B_UNICODE_OTHER_SYMBOL = 27, // So B_UNICODE_INITIAL_PUNCTUATION = 28, // Pi B_UNICODE_FINAL_PUNCTUATION = 29, // Pf - B_UNICODE_GENERAL_OTHER_TYPES = 30, // Cn B_UNICODE_CATEGORY_COUNT }; -/** - * This specifies the language directional property of a character set. - */ +// This specifies the language directional property of a character set. enum unicode_char_direction { - B_UNICODE_LEFT_TO_RIGHT = 0, - B_UNICODE_RIGHT_TO_LEFT = 1, - B_UNICODE_EUROPEAN_NUMBER = 2, - B_UNICODE_EUROPEAN_NUMBER_SEPARATOR = 3, - B_UNICODE_EUROPEAN_NUMBER_TERMINATOR = 4, - B_UNICODE_ARABIC_NUMBER = 5, - B_UNICODE_COMMON_NUMBER_SEPARATOR = 6, - B_UNICODE_BLOCK_SEPARATOR = 7, - B_UNICODE_SEGMENT_SEPARATOR = 8, - B_UNICODE_WHITE_SPACE_NEUTRAL = 9, - B_UNICODE_OTHER_NEUTRAL = 10, - B_UNICODE_LEFT_TO_RIGHT_EMBEDDING = 11, - B_UNICODE_LEFT_TO_RIGHT_OVERRIDE = 12, - B_UNICODE_RIGHT_TO_LEFT_ARABIC = 13, - B_UNICODE_RIGHT_TO_LEFT_EMBEDDING = 14, - B_UNICODE_RIGHT_TO_LEFT_OVERRIDE = 15, - B_UNICODE_POP_DIRECTIONAL_FORMAT = 16, - B_UNICODE_DIR_NON_SPACING_MARK = 17, - B_UNICODE_BOUNDARY_NEUTRAL = 18, + B_UNICODE_LEFT_TO_RIGHT = 0, + B_UNICODE_RIGHT_TO_LEFT = 1, + B_UNICODE_EUROPEAN_NUMBER = 2, + B_UNICODE_EUROPEAN_NUMBER_SEPARATOR = 3, + B_UNICODE_EUROPEAN_NUMBER_TERMINATOR = 4, + B_UNICODE_ARABIC_NUMBER = 5, + B_UNICODE_COMMON_NUMBER_SEPARATOR = 6, + B_UNICODE_BLOCK_SEPARATOR = 7, + B_UNICODE_SEGMENT_SEPARATOR = 8, + B_UNICODE_WHITE_SPACE_NEUTRAL = 9, + B_UNICODE_OTHER_NEUTRAL = 10, + B_UNICODE_LEFT_TO_RIGHT_EMBEDDING = 11, + B_UNICODE_LEFT_TO_RIGHT_OVERRIDE = 12, + B_UNICODE_RIGHT_TO_LEFT_ARABIC = 13, + B_UNICODE_RIGHT_TO_LEFT_EMBEDDING = 14, + B_UNICODE_RIGHT_TO_LEFT_OVERRIDE = 15, + B_UNICODE_POP_DIRECTIONAL_FORMAT = 16, + B_UNICODE_DIR_NON_SPACING_MARK = 17, + B_UNICODE_BOUNDARY_NEUTRAL = 18, B_UNICODE_DIRECTION_COUNT }; -/** - * Script range as defined in the Unicode standard. - */ +// Script range as defined in the Unicode standard. enum unicode_char_script { - // Script names - B_UNICODE_BASIC_LATIN, - B_UNICODE_LATIN_1_SUPPLEMENT, - B_UNICODE_LATIN_EXTENDED_A, - B_UNICODE_LATIN_EXTENDED_B, - B_UNICODE_IPA_EXTENSIONS, - B_UNICODE_SPACING_MODIFIER_LETTERS, - B_UNICODE_COMBINING_DIACRITICAL_MARKS, - B_UNICODE_GREEK, - B_UNICODE_CYRILLIC, - B_UNICODE_ARMENIAN, - B_UNICODE_HEBREW, - B_UNICODE_ARABIC, - B_UNICODE_SYRIAC, - B_UNICODE_THAANA, - B_UNICODE_DEVANAGARI, - B_UNICODE_BENGALI, - B_UNICODE_GURMUKHI, - B_UNICODE_GUJARATI, - B_UNICODE_ORIYA, - B_UNICODE_TAMIL, - B_UNICODE_TELUGU, - B_UNICODE_KANNADA, - B_UNICODE_MALAYALAM, - B_UNICODE_SINHALA, - B_UNICODE_THAI, - B_UNICODE_LAO, - B_UNICODE_TIBETAN, - B_UNICODE_MYANMAR, - B_UNICODE_GEORGIAN, - B_UNICODE_HANGUL_JAMO, - B_UNICODE_ETHIOPIC, - B_UNICODE_CHEROKEE, - B_UNICODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, - B_UNICODE_OGHAM, - B_UNICODE_RUNIC, - B_UNICODE_KHMER, - B_UNICODE_MONGOLIAN, - B_UNICODE_LATIN_EXTENDED_ADDITIONAL, - B_UNICODE_GREEK_EXTENDED, - B_UNICODE_GENERAL_PUNCTUATION, - B_UNICODE_SUPERSCRIPTS_AND_SUBSCRIPTS, - B_UNICODE_CURRENCY_SYMBOLS, - B_UNICODE_COMBINING_MARKS_FOR_SYMBOLS, - B_UNICODE_LETTERLIKE_SYMBOLS, - B_UNICODE_NUMBER_FORMS, - B_UNICODE_ARROWS, - B_UNICODE_MATHEMATICAL_OPERATORS, - B_UNICODE_MISCELLANEOUS_TECHNICAL, - B_UNICODE_CONTROL_PICTURES, - B_UNICODE_OPTICAL_CHARACTER_RECOGNITION, - B_UNICODE_ENCLOSED_ALPHANUMERICS, - B_UNICODE_BOX_DRAWING, - B_UNICODE_BLOCK_ELEMENTS, - B_UNICODE_GEOMETRIC_SHAPES, - B_UNICODE_MISCELLANEOUS_SYMBOLS, - B_UNICODE_DINGBATS, - B_UNICODE_BRAILLE_PATTERNS, - B_UNICODE_CJK_RADICALS_SUPPLEMENT, - B_UNICODE_KANGXI_RADICALS, - B_UNICODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS, - B_UNICODE_CJK_SYMBOLS_AND_PUNCTUATION, - B_UNICODE_HIRAGANA, - B_UNICODE_KATAKANA, - B_UNICODE_BOPOMOFO, - B_UNICODE_HANGUL_COMPATIBILITY_JAMO, - B_UNICODE_KANBUN, - B_UNICODE_BOPOMOFO_EXTENDED, - B_UNICODE_ENCLOSED_CJK_LETTERS_AND_MONTHS, - B_UNICODE_CJK_COMPATIBILITY, - B_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, - B_UNICODE_CJK_UNIFIED_IDEOGRAPHS, - B_UNICODE_YI_SYLLABLES, - B_UNICODE_YI_RADICALS, - B_UNICODE_HANGUL_SYLLABLES, - B_UNICODE_HIGH_SURROGATES, - B_UNICODE_HIGH_PRIVATE_USE_SURROGATES, - B_UNICODE_LOW_SURROGATES, - B_UNICODE_PRIVATE_USE_AREA, - B_UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS, - B_UNICODE_ALPHABETIC_PRESENTATION_FORMS, - B_UNICODE_ARABIC_PRESENTATION_FORMS_A, - B_UNICODE_COMBINING_HALF_MARKS, - B_UNICODE_CJK_COMPATIBILITY_FORMS, - B_UNICODE_SMALL_FORM_VARIANTS, - B_UNICODE_ARABIC_PRESENTATION_FORMS_B, - B_UNICODE_SPECIALS, - B_UNICODE_HALFWIDTH_AND_FULLWIDTH_FORMS, + // New No_Block value in Unicode 4. + B_UNICODE_NO_BLOCK = 0, // [none] Special range + B_UNICODE_BASIC_LATIN = 1, // [0000] + B_UNICODE_LATIN_1_SUPPLEMENT = 2, // [0080] + B_UNICODE_LATIN_EXTENDED_A = 3, // [0100] + B_UNICODE_LATIN_EXTENDED_B = 4, // [0180] + B_UNICODE_IPA_EXTENSIONS = 5, // [0250] + B_UNICODE_SPACING_MODIFIER_LETTERS = 6, // [02B0] + B_UNICODE_COMBINING_DIACRITICAL_MARKS = 7, // [0300] + B_UNICODE_GREEK = 8, // [0370] + B_UNICODE_CYRILLIC = 9, // [0400] + B_UNICODE_ARMENIAN = 10, // [0530] + B_UNICODE_HEBREW = 11, // [0590] + B_UNICODE_ARABIC = 12, // [0600] + B_UNICODE_SYRIAC = 13, // [0700] + B_UNICODE_THAANA = 14, // [0780] + B_UNICODE_DEVANAGARI = 15, // [0900] + B_UNICODE_BENGALI = 16, // [0980] + B_UNICODE_GURMUKHI = 17, // [0A00] + B_UNICODE_GUJARATI = 18, // [0A80] + B_UNICODE_ORIYA = 19, // [0B00] + B_UNICODE_TAMIL = 20, // [0B80] + B_UNICODE_TELUGU = 21, // [0C00] + B_UNICODE_KANNADA = 22, // [0C80] + B_UNICODE_MALAYALAM = 23, // [0D00] + B_UNICODE_SINHALA = 24, // [0D80] + B_UNICODE_THAI = 25, // [0E00] + B_UNICODE_LAO = 26, // [0E80] + B_UNICODE_TIBETAN = 27, // [0F00] + B_UNICODE_MYANMAR = 28, // [1000] + B_UNICODE_GEORGIAN = 29, // [10A0] + B_UNICODE_HANGUL_JAMO = 30, // [1100] + B_UNICODE_ETHIOPIC = 31, // [1200] + B_UNICODE_CHEROKEE = 32, // [13A0] + B_UNICODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS = 33, // [1400] + B_UNICODE_OGHAM = 34, // [1680] + B_UNICODE_RUNIC = 35, // [16A0] + B_UNICODE_KHMER = 36, // [1780] + B_UNICODE_MONGOLIAN = 37, // [1800] + B_UNICODE_LATIN_EXTENDED_ADDITIONAL = 38, // [1E00] + B_UNICODE_GREEK_EXTENDED = 39, // [1F00] + B_UNICODE_GENERAL_PUNCTUATION = 40, // [2000] + B_UNICODE_SUPERSCRIPTS_AND_SUBSCRIPTS = 41, // [2070] + B_UNICODE_CURRENCY_SYMBOLS = 42, // [20A0] + B_UNICODE_COMBINING_MARKS_FOR_SYMBOLS = 43, // [20D0] + B_UNICODE_LETTERLIKE_SYMBOLS = 44, // [2100] + B_UNICODE_NUMBER_FORMS = 45, // [2150] + B_UNICODE_ARROWS = 46, // [2190] + B_UNICODE_MATHEMATICAL_OPERATORS = 47, // [2200] + B_UNICODE_MISCELLANEOUS_TECHNICAL = 48, // [2300] + B_UNICODE_CONTROL_PICTURES = 49, // [2400] + B_UNICODE_OPTICAL_CHARACTER_RECOGNITION = 50, // [2440] + B_UNICODE_ENCLOSED_ALPHANUMERICS = 51, // [2460] + B_UNICODE_BOX_DRAWING = 52, // [2500] + B_UNICODE_BLOCK_ELEMENTS = 53, // [2580] + B_UNICODE_GEOMETRIC_SHAPES = 54, // [25A0] + B_UNICODE_MISCELLANEOUS_SYMBOLS = 55, // [2600] + B_UNICODE_DINGBATS = 56, // [2700] + B_UNICODE_BRAILLE_PATTERNS = 57, // [2800] + B_UNICODE_CJK_RADICALS_SUPPLEMENT = 58, // [2E80] + B_UNICODE_KANGXI_RADICALS = 59, // [2F00] + B_UNICODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS = 60, // [2FF0] + B_UNICODE_CJK_SYMBOLS_AND_PUNCTUATION = 61, // [3000] + B_UNICODE_HIRAGANA = 62, // [3040] + B_UNICODE_KATAKANA = 63, // [30A0] + B_UNICODE_BOPOMOFO = 64, // [3100] + B_UNICODE_HANGUL_COMPATIBILITY_JAMO = 65, // [3130] + B_UNICODE_KANBUN = 66, // [3190] + B_UNICODE_BOPOMOFO_EXTENDED = 67, // [31A0] + B_UNICODE_ENCLOSED_CJK_LETTERS_AND_MONTHS = 68, // [3200] + B_UNICODE_CJK_COMPATIBILITY = 69, // [3300] + B_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A = 70, // [3400] + B_UNICODE_CJK_UNIFIED_IDEOGRAPHS = 71, // [4E00] + B_UNICODE_YI_SYLLABLES = 72, // [A000] + B_UNICODE_YI_RADICALS = 73, // [A490] + B_UNICODE_HANGUL_SYLLABLES = 74, // [AC00] + B_UNICODE_HIGH_SURROGATES = 75, // [D800] + B_UNICODE_HIGH_PRIVATE_USE_SURROGATES = 76, // [DB80] + B_UNICODE_LOW_SURROGATES = 77, // [DC00] + B_UNICODE_PRIVATE_USE = 78, + B_UNICODE_PRIVATE_USE_AREA = B_UNICODE_PRIVATE_USE, // [E000] + B_UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS = 79, // [F900] + B_UNICODE_ALPHABETIC_PRESENTATION_FORMS = 80, // [FB00] + B_UNICODE_ARABIC_PRESENTATION_FORMS_A = 81, // [FB50] + B_UNICODE_COMBINING_HALF_MARKS = 82, // [FE20] + B_UNICODE_CJK_COMPATIBILITY_FORMS = 83, // [FE30] + B_UNICODE_SMALL_FORM_VARIANTS = 84, // [FE50] + B_UNICODE_ARABIC_PRESENTATION_FORMS_B = 85, // [FE70] + B_UNICODE_SPECIALS = 86, // [FFF0] + B_UNICODE_HALFWIDTH_AND_FULLWIDTH_FORMS = 87, // [FF00] - B_UNICODE_SCRIPT_COUNT, - B_UNICODE_NO_SCRIPT = B_UNICODE_SCRIPT_COUNT + // New blocks in Unicode 3.1 + B_UNICODE_OLD_ITALIC = 88, // [10300] + B_UNICODE_GOTHIC = 89, // [10330] + B_UNICODE_DESERET = 90, // [10400] + B_UNICODE_BYZANTINE_MUSICAL_SYMBOLS = 91, // [1D000] + B_UNICODE_MUSICAL_SYMBOLS = 92, // [1D100] + B_UNICODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS = 93, // [1D400] + B_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B = 94, // [20000] + B_UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = 95, // [2F800] + B_UNICODE_TAGS = 96, // [E0000] + + // New blocks in Unicode + B_UNICODE_CYRILLIC_SUPPLEMENTARY = 97, + B_UNICODE_CYRILLIC_SUPPLEMENT = B_UNICODE_CYRILLIC_SUPPLEMENTARY, // [0500] + B_UNICODE_TAGALOG = 98, // [1700] + B_UNICODE_HANUNOO = 99, // [1720] + B_UNICODE_BUHID = 100, // [1740] + B_UNICODE_TAGBANWA = 101, // [1760] + B_UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = 102, // [27C0] + B_UNICODE_SUPPLEMENTAL_ARROWS_A = 103, // [27F0] + B_UNICODE_SUPPLEMENTAL_ARROWS_B = 104, // [2900] + B_UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = 105, // [2980] + B_UNICODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS = 106, // [2A00] + B_UNICODE_KATAKANA_PHONETIC_EXTENSIONS = 107, // [31F0] + B_UNICODE_VARIATION_SELECTORS = 108, // [FE00] + B_UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A = 109, // [F0000] + B_UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B = 110, // [100000] + + // New blocks in Unicode 4 + B_UNICODE_LIMBU = 111, // [1900] + B_UNICODE_TAI_LE = 112, // [1950] + B_UNICODE_KHMER_SYMBOLS = 113, // [19E0] + B_UNICODE_PHONETIC_EXTENSIONS = 114, // [1D00] + B_UNICODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS = 115, // [2B00] + B_UNICODE_YIJING_HEXAGRAM_SYMBOLS = 116, // [4DC0] + B_UNICODE_LINEAR_B_SYLLABARY = 117, // [10000] + B_UNICODE_LINEAR_B_IDEOGRAMS = 118, // [10080] + B_UNICODE_AEGEAN_NUMBERS = 119, // [10100] + B_UNICODE_UGARITIC = 120, // [10380] + B_UNICODE_SHAVIAN = 121, // [10450] + B_UNICODE_OSMANYA = 122, // [10480] + B_UNICODE_CYPRIOT_SYLLABARY = 123, // [10800] + B_UNICODE_TAI_XUAN_JING_SYMBOLS = 124, // [1D300] + B_UNICODE_VARIATION_SELECTORS_SUPPLEMENT = 125, // [E0100] + + // New blocks in Unicode 4.1 + B_UNICODE_ANCIENT_GREEK_MUSICAL_NOTATION = 126, // [1D200] + B_UNICODE_ANCIENT_GREEK_NUMBERS = 127, // [10140] + B_UNICODE_ARABIC_SUPPLEMENT = 128, // [0750] + B_UNICODE_BUGINESE = 129, // [1A00] + B_UNICODE_CJK_STROKES = 130, // [31C0] + B_UNICODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT = 131, // [1DC0] + B_UNICODE_COPTIC = 132, // [2C80] + B_UNICODE_ETHIOPIC_EXTENDED = 133, // [2D80] + B_UNICODE_ETHIOPIC_SUPPLEMENT = 134, // [1380] + B_UNICODE_GEORGIAN_SUPPLEMENT = 135, // [2D00] + B_UNICODE_GLAGOLITIC = 136, // [2C00] + B_UNICODE_KHAROSHTHI = 137, // [10A00] + B_UNICODE_MODIFIER_TONE_LETTERS = 138, // [A700] + B_UNICODE_NEW_TAI_LUE = 139, // [1980] + B_UNICODE_OLD_PERSIAN = 140, // [103A0] + B_UNICODE_PHONETIC_EXTENSIONS_SUPPLEMENT = 141, // [1D80] + B_UNICODE_SUPPLEMENTAL_PUNCTUATION = 142, // [2E00] + B_UNICODE_SYLOTI_NAGRI = 143, // [A800] + B_UNICODE_TIFINAGH = 144, // [2D30] + B_UNICODE_VERTICAL_FORMS = 145, // [FE10] + + // New blocks in Unicode 5.0 + B_UNICODE_NKO = 146, // [07C0] + B_UNICODE_BALINESE = 147, // [1B00] + B_UNICODE_LATIN_EXTENDED_C = 148, // [2C60] + B_UNICODE_LATIN_EXTENDED_D = 149, // [A720] + B_UNICODE_PHAGS_PA = 150, // [A840] + B_UNICODE_PHOENICIAN = 151, // [10900] + B_UNICODE_CUNEIFORM = 152, // [12000] + B_UNICODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION = 153, // [12400] + B_UNICODE_COUNTING_ROD_NUMERALS = 154, // [1D360] + + // New blocks in Unicode 5.1 + B_UNICODE_SUNDANESE = 155, // [1B80] + B_UNICODE_LEPCHA = 156, // [1C00] + B_UNICODE_OL_CHIKI = 157, // [1C50] + B_UNICODE_CYRILLIC_EXTENDED_A = 158, // [2DE0] + B_UNICODE_VAI = 159, // [A500] + B_UNICODE_CYRILLIC_EXTENDED_B = 160, // [A640] + B_UNICODE_SAURASHTRA = 161, // [A880] + B_UNICODE_KAYAH_LI = 162, // [A900] + B_UNICODE_REJANG = 163, // [A930] + B_UNICODE_CHAM = 164, // [AA00] + B_UNICODE_ANCIENT_SYMBOLS = 165, // [10190] + B_UNICODE_PHAISTOS_DISC = 166, // [101D0] + B_UNICODE_LYCIAN = 167, // [10280] + B_UNICODE_CARIAN = 168, // [102A0] + B_UNICODE_LYDIAN = 169, // [10920] + B_UNICODE_MAHJONG_TILES = 170, // [1F000] + B_UNICODE_DOMINO_TILES = 171, // [1F030] + + // New blocks in Unicode 5.2 + B_UNICODE_SAMARITAN = 172, // [0800] + B_UNICODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED = 173, // [18B0] + B_UNICODE_TAI_THAM = 174, // [1A20] + B_UNICODE_VEDIC_EXTENSIONS = 175, // [1CD0] + B_UNICODE_LISU = 176, // [A4D0] + B_UNICODE_BAMUM = 177, // [A6A0] + B_UNICODE_COMMON_INDIC_NUMBER_FORMS = 178, // [A830] + B_UNICODE_DEVANAGARI_EXTENDED = 179, // [A8E0] + B_UNICODE_HANGUL_JAMO_EXTENDED_A = 180, // [A960] + B_UNICODE_JAVANESE = 181, // [A980] + B_UNICODE_MYANMAR_EXTENDED_A = 182, // [AA60] + B_UNICODE_TAI_VIET = 183, // [AA80] + B_UNICODE_MEETEI_MAYEK = 184, // [ABC0] + B_UNICODE_HANGUL_JAMO_EXTENDED_B = 185, // [D7B0] + B_UNICODE_IMPERIAL_ARAMAIC = 186, // [10840] + B_UNICODE_OLD_SOUTH_ARABIAN = 187, // [10A60] + B_UNICODE_AVESTAN = 188, // [10B00] + B_UNICODE_INSCRIPTIONAL_PARTHIAN = 189, // [10B40] + B_UNICODE_INSCRIPTIONAL_PAHLAVI = 190, // [10B60] + B_UNICODE_OLD_TURKIC = 191, // [10C00] + B_UNICODE_RUMI_NUMERAL_SYMBOLS = 192, // [10E60] + B_UNICODE_KAITHI = 193, // [11080] + B_UNICODE_EGYPTIAN_HIEROGLYPHS = 194, // [13000] + B_UNICODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT = 195, // [1F100] + B_UNICODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT = 196, // [1F200] + B_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C = 197, // [2A700] + + // New blocks in Unicode 6.0 + B_UNICODE_MANDAIC = 198, // [0840] + B_UNICODE_BATAK = 199, // [1BC0] + B_UNICODE_ETHIOPIC_EXTENDED_A = 200, // [AB00] + B_UNICODE_BRAHMI = 201, // [11000] + B_UNICODE_BAMUM_SUPPLEMENT = 202, // [16800] + B_UNICODE_KANA_SUPPLEMENT = 203, // [1B000] + B_UNICODE_PLAYING_CARDS = 204, // [1F0A0] + B_UNICODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS = 205, // [1F300] + B_UNICODE_EMOTICONS = 206, // [1F600] + B_UNICODE_TRANSPORT_AND_MAP_SYMBOLS = 207, // [1F680] + B_UNICODE_ALCHEMICAL_SYMBOLS = 208, // [1F700] + B_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D = 209, // [2B740] + + B_UNICODE_SCRIPT_COUNT = 210, + B_UNICODE_NO_SCRIPT = B_UNICODE_SCRIPT_COUNT, + + B_UNICODE_INVALID_CODE = -1 }; -/** - * Values returned by the u_getCellWidth() function. - */ +// East Asian Width constants. -enum unicode_cell_width +enum unicode_east_asian_width { - B_UNICODE_ZERO_WIDTH = 0, - B_UNICODE_HALF_WIDTH = 1, - B_UNICODE_FULL_WIDTH = 2, - B_UNICODE_NEUTRAL_WIDTH = 3, - - B_UNICODE_CELL_WIDTH_COUNT + B_UNICODE_EA_NEUTRAL, // [N] + B_UNICODE_EA_AMBIGUOUS, // [A] + B_UNICODE_EA_HALFWIDTH, // [H] + B_UNICODE_EA_FULLWIDTH, // [F] + B_UNICODE_EA_NARROW, // [Na] + B_UNICODE_EA_WIDE, // [W] + B_UNICODE_EA_COUNT }; @@ -209,6 +347,7 @@ class BUnicodeChar { static uint32 ToUpper(uint32 c); static uint32 ToTitle(uint32 c); static int32 DigitValue(uint32 c); + static unicode_east_asian_width EastAsianWidth(uint32 c); static void ToUTF8(uint32 c, char **out); static uint32 FromUTF8(const char **in); @@ -230,4 +369,4 @@ BUnicodeChar::FromUTF8(const char *in) } -#endif /* _UNICODE_CHAR_H_ */ +#endif // _UNICODE_CHAR_H_ diff --git a/headers/os/support/UTF8.h b/headers/os/support/UTF8.h index c411d2b53b..ab5416a696 100644 --- a/headers/os/support/UTF8.h +++ b/headers/os/support/UTF8.h @@ -39,7 +39,8 @@ enum { B_ISO15_CONVERSION, B_BIG5_CONVERSION, // Chinese Big5 B_GBK_CONVERSION, // Chinese GB18030 - B_UTF16_CONVERSION // Unicode UTF-16 + B_UTF16_CONVERSION, // Unicode UTF-16 + B_MS_WINDOWS_1250_CONVERSION // Windows Central European Codepage }; diff --git a/headers/posix/resolv.h b/headers/posix/resolv.h index 2b1b569b1f..bb600068d1 100644 --- a/headers/posix/resolv.h +++ b/headers/posix/resolv.h @@ -238,6 +238,7 @@ union res_sockaddr_union { #define RES_NOTLDQUERY 0x00100000 /* don't unqualified name as a tld */ #define RES_USE_DNSSEC 0x00200000 /* use DNSSEC using OK bit in OPT */ /* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */ +#define RES_USE_INET4 0x00800000 /* use IPv4 in gethostbyname() */ /* KAME extensions: use higher bit to avoid conflict with ISC use */ #define RES_USE_DNAME 0x10000000 /* use DNAME */ #define RES_USE_EDNS0 0x40000000 /* use EDNS0 if configured */ diff --git a/headers/private/app/ServerReadOnlyMemory.h b/headers/private/app/ServerReadOnlyMemory.h index 64b29f2634..238498111b 100644 --- a/headers/private/app/ServerReadOnlyMemory.h +++ b/headers/private/app/ServerReadOnlyMemory.h @@ -13,23 +13,25 @@ #include -static const int32 kNumColors = 34; +// Update this constant with the largest color constant excluding +// B_SUCCESS_COLOR and B_FAILURE_COLOR. +// If you add a constant with index greater than 100 you'll have to add +// to the second operand. +static const int32 kColorWhichCount = B_SCROLL_BAR_THUMB_COLOR + 3; + struct server_read_only_memory { - rgb_color colors[kNumColors]; + rgb_color colors[kColorWhichCount]; }; -// NOTE: these functions must be kept in sync with InterfaceDefs.h color_which! - static inline int32 color_which_to_index(color_which which) { - // NOTE: this must be kept in sync with InterfaceDefs.h color_which! - if (which <= B_LIST_SELECTED_ITEM_TEXT_COLOR) + if (which <= kColorWhichCount - 3) return which - 1; if (which >= B_SUCCESS_COLOR && which <= B_FAILURE_COLOR) - return which - B_SUCCESS_COLOR + B_LIST_SELECTED_ITEM_TEXT_COLOR; + return which - B_SUCCESS_COLOR + kColorWhichCount - 3; return -1; } @@ -38,12 +40,12 @@ color_which_to_index(color_which which) static inline color_which index_to_color_which(int32 index) { - if (index >= 0 && index < kNumColors) { - if ((color_which)index < B_LIST_SELECTED_ITEM_TEXT_COLOR) + if (index >= 0 && index < kColorWhichCount) { + if ((color_which)index < kColorWhichCount - 3) return (color_which)(index + 1); else { return (color_which)(index + B_SUCCESS_COLOR - - B_LIST_SELECTED_ITEM_TEXT_COLOR); + - kColorWhichCount - 3); } } diff --git a/headers/private/kernel/arch/arm/arch_kernel.h b/headers/private/kernel/arch/arm/arch_kernel.h index 44a05e74a6..766ab42b10 100644 --- a/headers/private/kernel/arch/arm/arch_kernel.h +++ b/headers/private/kernel/arch/arm/arch_kernel.h @@ -25,7 +25,7 @@ #define USER_SIZE (0x80000000 - (0x10000 + 0x100000)) #define USER_TOP (USER_BASE + (USER_SIZE - 1)) -#define KERNEL_USER_DATA_BASE 0x6fff0000 +#define KERNEL_USER_DATA_BASE 0x60000000 #define USER_STACK_REGION 0x70000000 #define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) diff --git a/headers/private/kernel/arch/m68k/arch_kernel.h b/headers/private/kernel/arch/m68k/arch_kernel.h index 7f9806999a..cef14fb2f0 100644 --- a/headers/private/kernel/arch/m68k/arch_kernel.h +++ b/headers/private/kernel/arch/m68k/arch_kernel.h @@ -25,7 +25,7 @@ #define USER_SIZE (0x80000000 - (0x10000 + 0x100000)) #define USER_TOP (USER_BASE + (USER_SIZE - 1)) -#define KERNEL_USER_DATA_BASE 0x6fff0000 +#define KERNEL_USER_DATA_BASE 0x60000000 #define USER_STACK_REGION 0x70000000 #define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) diff --git a/headers/private/kernel/arch/mipsel/arch_kernel.h b/headers/private/kernel/arch/mipsel/arch_kernel.h index 42f3c8fbaf..237459177d 100644 --- a/headers/private/kernel/arch/mipsel/arch_kernel.h +++ b/headers/private/kernel/arch/mipsel/arch_kernel.h @@ -28,7 +28,7 @@ #define USER_SIZE (0x80000000 - (0x10000 + 0x100000)) #define USER_TOP (USER_BASE + (USER_SIZE - 1)) -#define KERNEL_USER_DATA_BASE 0x6fff0000 +#define KERNEL_USER_DATA_BASE 0x60000000 #define USER_STACK_REGION 0x70000000 #define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) diff --git a/headers/private/kernel/arch/ppc/arch_kernel.h b/headers/private/kernel/arch/ppc/arch_kernel.h index c7d448084b..803a9aade7 100644 --- a/headers/private/kernel/arch/ppc/arch_kernel.h +++ b/headers/private/kernel/arch/ppc/arch_kernel.h @@ -25,7 +25,7 @@ #define USER_SIZE (0x80000000 - (0x10000 + 0x100000)) #define USER_TOP (USER_BASE + (USER_SIZE - 1)) -#define KERNEL_USER_DATA_BASE 0x6fff0000 +#define KERNEL_USER_DATA_BASE 0x60000000 #define USER_STACK_REGION 0x70000000 #define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index 58694f3423..bc9f4c8599 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -39,6 +39,11 @@ #define IA32_MSR_EFER 0xc0000080 +// MSR EFER bits +// reference +#define IA32_MSR_EFER_SYSCALL (1 << 0) +#define IA32_MSR_EFER_NX (1 << 11) + // x86_64 MSRs. #define IA32_MSR_STAR 0xc0000081 #define IA32_MSR_LSTAR 0xc0000082 @@ -131,6 +136,13 @@ #define IA32_FEATURE_AMD_EXT_3DNOWEXT (1 << 30) // 3DNow! extensions #define IA32_FEATURE_AMD_EXT_3DNOW (1 << 31) // 3DNow! +// some of the features from cpuid eax 0x80000001, edx register (AMD) are also +// available on Intel processors +#define IA32_FEATURES_INTEL_EXT (IA32_FEATURE_AMD_EXT_SYSCALL \ + | IA32_FEATURE_AMD_EXT_NX \ + | IA32_FEATURE_AMD_EXT_RDTSCP \ + | IA32_FEATURE_AMD_EXT_LONG) + // x86 defined features from cpuid eax 6, eax register // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11) #define IA32_FEATURE_DTS (1 << 0) //Digital Thermal Sensor diff --git a/headers/private/kernel/arch/x86/arch_kernel.h b/headers/private/kernel/arch/x86/arch_kernel.h index 02f9b1588c..f5d6c4dba4 100644 --- a/headers/private/kernel/arch/x86/arch_kernel.h +++ b/headers/private/kernel/arch/x86/arch_kernel.h @@ -48,8 +48,8 @@ #define USER_SIZE (0x800000000000 - 0x200000) #define USER_TOP (USER_BASE + (USER_SIZE - 1)) -#define KERNEL_USER_DATA_BASE 0x7fffefff0000 -#define USER_STACK_REGION 0x7ffff0000000 +#define KERNEL_USER_DATA_BASE 0x7f0000000000 +#define USER_STACK_REGION 0x7f0000000000 #define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) @@ -76,7 +76,7 @@ #define USER_SIZE (KERNEL_BASE - 0x10000) #define USER_TOP (USER_BASE + (USER_SIZE - 1)) -#define KERNEL_USER_DATA_BASE 0x6fff0000 +#define KERNEL_USER_DATA_BASE 0x60000000 #define USER_STACK_REGION 0x70000000 #define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) diff --git a/headers/private/kernel/commpage.h b/headers/private/kernel/commpage.h index b30f82a4cb..dd8ac97612 100644 --- a/headers/private/kernel/commpage.h +++ b/headers/private/kernel/commpage.h @@ -18,8 +18,9 @@ extern "C" { status_t commpage_init(void); status_t commpage_init_post_cpus(void); void* allocate_commpage_entry(int entry, size_t size); -void* fill_commpage_entry(int entry, const void* copyFrom, size_t size); +addr_t fill_commpage_entry(int entry, const void* copyFrom, size_t size); image_id get_commpage_image(); +area_id clone_commpage_area(team_id team, void** address); // implemented in the architecture specific part status_t arch_commpage_init(void); diff --git a/headers/private/kernel/ksignal.h b/headers/private/kernel/ksignal.h index b7ec3c3bab..4727053c8d 100644 --- a/headers/private/kernel/ksignal.h +++ b/headers/private/kernel/ksignal.h @@ -52,6 +52,7 @@ struct signal_frame_data { int32 thread_flags; uint64 syscall_restart_return_value; uint8 syscall_restart_parameters[SYSCALL_RESTART_PARAMETER_SIZE]; + void* commpage_address; }; diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 78e893da3b..1c06271a50 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -259,6 +259,8 @@ struct Team : TeamThreadIteratorEntry, KernelReferenceable, size_t used_user_data; struct free_user_thread* free_user_threads; + void* commpage_address; + struct team_debug_info debug_info; // protected by scheduler lock diff --git a/headers/private/kernel/util/Random.h b/headers/private/kernel/util/Random.h new file mode 100644 index 0000000000..d30976d198 --- /dev/null +++ b/headers/private/kernel/util/Random.h @@ -0,0 +1,87 @@ +/* + * Copyright 2013 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ +#ifndef KERNEL_UTIL_RANDOM_H +#define KERNEL_UTIL_RANDOM_H + + +#include +#include + + +#define MAX_FAST_RANDOM_VALUE 0x7fff +#define MAX_RANDOM_VALUE 0x7fffffffu +#define MAX_SECURE_RANDOM_VALUE 0xffffffffu + +static const int kFastRandomShift = 15; +static const int kRandomShift = 31; +static const int kSecureRandomShift = 32; + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int fast_random_value(void); +unsigned int random_value(void); +unsigned int secure_random_value(void); + +#ifdef __cplusplus +} +#endif + + +#ifdef __cplusplus + +template +T +fast_get_random() +{ + size_t shift = 0; + T random = 0; + while (shift < sizeof(T) * 8) { + random |= (T)fast_random_value() << shift; + shift += kFastRandomShift; + } + + return random; +} + + +template +T +get_random() +{ + size_t shift = 0; + T random = 0; + while (shift < sizeof(T) * 8) { + random |= (T)random_value() << shift; + shift += kRandomShift; + } + + return random; +} + + +template +T +secure_get_random() +{ + size_t shift = 0; + T random = 0; + while (shift < sizeof(T) * 8) { + random |= (T)secure_random_value() << shift; + shift += kSecureRandomShift; + } + + return random; +} + + +#endif // __cplusplus + +#endif // KERNEL_UTIL_RANDOM_H + diff --git a/headers/private/kernel/vm/vm.h b/headers/private/kernel/vm/vm.h index bd9fd16aa8..1962f418a2 100644 --- a/headers/private/kernel/vm/vm.h +++ b/headers/private/kernel/vm/vm.h @@ -121,6 +121,8 @@ status_t vm_delete_area(team_id teamID, area_id areaID, bool kernel); status_t vm_create_vnode_cache(struct vnode *vnode, struct VMCache **_cache); status_t vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type); +status_t vm_set_area_protection(team_id team, area_id areaID, + uint32 newProtection, bool kernel); status_t vm_get_page_mapping(team_id team, addr_t vaddr, phys_addr_t *paddr); bool vm_test_map_modification(struct vm_page *page); void vm_clear_map_flags(struct vm_page *page, uint32 flags); diff --git a/headers/private/kernel/vm/vm_priv.h b/headers/private/kernel/vm/vm_priv.h index afb15a714a..9091c60c81 100644 --- a/headers/private/kernel/vm/vm_priv.h +++ b/headers/private/kernel/vm/vm_priv.h @@ -28,7 +28,7 @@ extern "C" { // Should only be used by vm internals status_t vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, - bool isUser, addr_t *newip); + bool isExecute, bool isUser, addr_t *newip); void vm_unreserve_memory(size_t bytes); status_t vm_try_reserve_memory(size_t bytes, int priority, bigtime_t timeout); status_t vm_daemon_init(void); diff --git a/headers/private/libroot/libroot_private.h b/headers/private/libroot/libroot_private.h index 7a3357b614..593ffd3526 100644 --- a/headers/private/libroot/libroot_private.h +++ b/headers/private/libroot/libroot_private.h @@ -34,7 +34,7 @@ void __init_env(const struct user_space_program_args *args); void __init_heap(void); void __init_heap_post_env(void); -void __init_time(void); +void __init_time(addr_t commPageTable); void __arch_init_time(struct real_time_data *data, bool setDefaults); bigtime_t __arch_get_system_time_offset(struct real_time_data *data); bigtime_t __get_system_time_offset(); diff --git a/headers/private/net/NetServer.h b/headers/private/net/NetServer.h index 9b66ad9a0f..d0d1bf13ef 100644 --- a/headers/private/net/NetServer.h +++ b/headers/private/net/NetServer.h @@ -19,6 +19,7 @@ #define kMsgRemovePersistentNetwork 'RPnw' #define kMsgJoinNetwork 'JNnw' #define kMsgLeaveNetwork 'LVnw' +#define kMsgAutoJoinNetwork 'AJnw' #endif // _NET_SERVER_H diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index cc9b96cd98..39e675f8a9 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -51,6 +51,7 @@ struct rld_export { void (*call_termination_hooks)(); const struct user_space_program_args *program_args; + const void* commpage_address; }; extern struct rld_export *__gRuntimeLoader; diff --git a/headers/private/shared/cpu_type.h b/headers/private/shared/cpu_type.h index d6f4fba391..d71983e14f 100644 --- a/headers/private/shared/cpu_type.h +++ b/headers/private/shared/cpu_type.h @@ -19,7 +19,7 @@ extern "C" { #endif const char *get_cpu_vendor_string(enum cpu_types type); -const char *get_cpu_model_string(system_info *info); +const char *get_cpu_model_string(const system_info *info); void get_cpu_type(char *vendorBuffer, size_t vendorSize, char *modelBuffer, size_t modelSize); int32 get_rounded_cpu_speed(void); @@ -257,7 +257,7 @@ get_cpuid_model_string(char *name) const char * -get_cpu_model_string(system_info *info) +get_cpu_model_string(const system_info *info) { #if defined(__INTEL__) || defined(__x86_64__) char cpuidName[49]; diff --git a/headers/private/system/arch/arm/arch_commpage_defs.h b/headers/private/system/arch/arm/arch_commpage_defs.h index 57fb821e96..39bf6f641d 100644 --- a/headers/private/system/arch/arm/arch_commpage_defs.h +++ b/headers/private/system/arch/arm/arch_commpage_defs.h @@ -12,8 +12,4 @@ //#define COMMPAGE_ENTRY_M68K_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) //#define COMMPAGE_ENTRY_M68K_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -/* 0xffff0000 colides with IO space mapped with TT1 on Atari */ -#warning ARM: determine good place for compage.. -#define ARCH_USER_COMMPAGE_ADDR (0xfeff0000) - #endif /* _SYSTEM_ARCH_M68K_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/m68k/arch_commpage_defs.h b/headers/private/system/arch/m68k/arch_commpage_defs.h index 0b6d6e354d..71bc119904 100644 --- a/headers/private/system/arch/m68k/arch_commpage_defs.h +++ b/headers/private/system/arch/m68k/arch_commpage_defs.h @@ -12,7 +12,4 @@ #define COMMPAGE_ENTRY_M68K_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_M68K_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -/* 0xffff0000 colides with IO space mapped with TT1 on Atari */ -#define ARCH_USER_COMMPAGE_ADDR (0xfeff0000) - #endif /* _SYSTEM_ARCH_M68K_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/mipsel/arch_commpage_defs.h b/headers/private/system/arch/mipsel/arch_commpage_defs.h index 64320ef662..516877d8be 100644 --- a/headers/private/system/arch/mipsel/arch_commpage_defs.h +++ b/headers/private/system/arch/mipsel/arch_commpage_defs.h @@ -14,7 +14,5 @@ #define COMMPAGE_ENTRY_MIPSEL_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_MIPSEL_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -#define ARCH_USER_COMMPAGE_ADDR (0xffff0000) - #endif /* _SYSTEM_ARCH_MIPSEL_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/ppc/arch_commpage_defs.h b/headers/private/system/arch/ppc/arch_commpage_defs.h index 419d388a1a..d2cd8cbe6c 100644 --- a/headers/private/system/arch/ppc/arch_commpage_defs.h +++ b/headers/private/system/arch/ppc/arch_commpage_defs.h @@ -12,6 +12,4 @@ #define COMMPAGE_ENTRY_PPC_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_PPC_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -#define ARCH_USER_COMMPAGE_ADDR (0xffff0000) - #endif /* _SYSTEM_ARCH_PPC_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/x86/arch_commpage_defs.h b/headers/private/system/arch/x86/arch_commpage_defs.h index 5f27f676ee..f2bda3e148 100644 --- a/headers/private/system/arch/x86/arch_commpage_defs.h +++ b/headers/private/system/arch/x86/arch_commpage_defs.h @@ -16,7 +16,7 @@ (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3) #define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS \ (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 4) - -#define ARCH_USER_COMMPAGE_ADDR (0xffff0000) +#define COMMPAGE_ENTRY_X86_THREAD_EXIT \ + (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 5) #endif /* _SYSTEM_ARCH_x86_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/x86_64/arch_commpage_defs.h b/headers/private/system/arch/x86_64/arch_commpage_defs.h index bf7809e38a..85fa54e104 100644 --- a/headers/private/system/arch/x86_64/arch_commpage_defs.h +++ b/headers/private/system/arch/x86_64/arch_commpage_defs.h @@ -13,7 +13,7 @@ #define COMMPAGE_ENTRY_X86_MEMSET (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) #define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER \ (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 2) - -#define ARCH_USER_COMMPAGE_ADDR (0xffffffffffff0000) +#define COMMPAGE_ENTRY_X86_THREAD_EXIT \ + (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3) #endif /* _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/commpage_defs.h b/headers/private/system/commpage_defs.h index c47c0b828d..0a69403182 100644 --- a/headers/private/system/commpage_defs.h +++ b/headers/private/system/commpage_defs.h @@ -19,11 +19,6 @@ #define COMMPAGE_SIGNATURE 'COMM' #define COMMPAGE_VERSION 1 -#define USER_COMMPAGE_ADDR ARCH_USER_COMMPAGE_ADDR - // set by the architecture specific implementation - -#define USER_COMMPAGE_TABLE ((void**)(USER_COMMPAGE_ADDR)) - #include #endif /* _SYSTEM_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h index 2d559378f4..3d7a3c1654 100644 --- a/headers/private/system/thread_defs.h +++ b/headers/private/system/thread_defs.h @@ -15,7 +15,7 @@ #define USER_STACK_GUARD_SIZE (4 * B_PAGE_SIZE) // 16 kB #define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB #define USER_STACK_SIZE (256 * 1024) // 256 kB -#define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB +#define MIN_USER_STACK_SIZE (8 * 1024) // 8 kB #define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB diff --git a/src/add-ons/accelerants/radeon/GetAccelerantHook.c b/src/add-ons/accelerants/radeon/GetAccelerantHook.c index 7744f65e3c..b7400bf4e5 100644 --- a/src/add-ons/accelerants/radeon/GetAccelerantHook.c +++ b/src/add-ons/accelerants/radeon/GetAccelerantHook.c @@ -72,9 +72,10 @@ initialization process. HOOK(SET_DPMS_MODE); /* cursor managment */ - HOOK(SET_CURSOR_SHAPE); - HOOK(MOVE_CURSOR); - HOOK(SHOW_CURSOR); +// TODO: fix +// HOOK(SET_CURSOR_SHAPE); +// HOOK(MOVE_CURSOR); +// HOOK(SHOW_CURSOR); /* synchronization */ HOOK(ACCELERANT_ENGINE_COUNT); diff --git a/src/add-ons/kernel/drivers/network/usb_asix/ASIXDevice.cpp b/src/add-ons/kernel/drivers/network/usb_asix/ASIXDevice.cpp index e7781adbbe..49cd5803d2 100644 --- a/src/add-ons/kernel/drivers/network/usb_asix/ASIXDevice.cpp +++ b/src/add-ons/kernel/drivers/network/usb_asix/ASIXDevice.cpp @@ -37,29 +37,29 @@ struct TRXHeader { ASIXDevice::ASIXDevice(usb_device device, DeviceInfo& deviceInfo) - : - fDevice(device), - fStatus(B_ERROR), - fOpen(false), - fRemoved(false), - fHasConnection(false), - fNonBlocking(false), - fInsideNotify(0), - fFrameSize(0), - fNotifyEndpoint(0), - fReadEndpoint(0), - fWriteEndpoint(0), - fActualLengthRead(0), - fActualLengthWrite(0), - fStatusRead(B_OK), - fStatusWrite(B_OK), - fNotifyReadSem(-1), - fNotifyWriteSem(-1), - fNotifyBuffer(NULL), - fNotifyBufferLength(0), - fLinkStateChangeSem(-1), - fUseTRXHeader(false), - fReadNodeIDRequest(kInvalidRequest) + : + fDevice(device), + fStatus(B_ERROR), + fOpen(false), + fRemoved(false), + fHasConnection(false), + fNonBlocking(false), + fInsideNotify(0), + fFrameSize(0), + fNotifyEndpoint(0), + fReadEndpoint(0), + fWriteEndpoint(0), + fActualLengthRead(0), + fActualLengthWrite(0), + fStatusRead(B_OK), + fStatusWrite(B_OK), + fNotifyReadSem(-1), + fNotifyWriteSem(-1), + fNotifyBuffer(NULL), + fNotifyBufferLength(0), + fLinkStateChangeSem(-1), + fUseTRXHeader(false), + fReadNodeIDRequest(kInvalidRequest) { fDeviceInfo = deviceInfo; @@ -72,14 +72,14 @@ ASIXDevice::ASIXDevice(usb_device device, DeviceInfo& deviceInfo) fNotifyReadSem = create_sem(0, DRIVER_NAME"_notify_read"); if (fNotifyReadSem < B_OK) { TRACE_ALWAYS("Error of creating read notify semaphore:%#010x\n", - fNotifyReadSem); + fNotifyReadSem); return; } fNotifyWriteSem = create_sem(0, DRIVER_NAME"_notify_write"); if (fNotifyWriteSem < B_OK) { TRACE_ALWAYS("Error of creating write notify semaphore:%#010x\n", - fNotifyWriteSem); + fNotifyWriteSem); return; } @@ -122,7 +122,7 @@ ASIXDevice::Open(uint32 flags) // setup state notifications result = gUSBModule->queue_interrupt(fNotifyEndpoint, fNotifyBuffer, - fNotifyBufferLength, _NotifyCallback, this); + fNotifyBufferLength, _NotifyCallback, this); if (result != B_OK) { TRACE_ALWAYS("Error of requesting notify interrupt:%#010x\n", result); return result; @@ -170,7 +170,7 @@ ASIXDevice::Read(uint8 *buffer, size_t *numBytes) if (fRemoved) { TRACE_ALWAYS("Error of receiving %d bytes from removed device.\n", - numBytesToRead); + numBytesToRead); return B_DEVICE_NOT_FOUND; } @@ -186,7 +186,8 @@ ASIXDevice::Read(uint8 *buffer, size_t *numBytes) size_t chunkCount = fUseTRXHeader ? 2 : 1 ; status_t result = gUSBModule->queue_bulk_v(fReadEndpoint, - &rxData[startIndex], chunkCount, _ReadCallback, this); + &rxData[startIndex], chunkCount, _ReadCallback, this); + if (result != B_OK) { TRACE_ALWAYS("Error of queue_bulk_v request:%#010x\n", result); return result; @@ -205,7 +206,7 @@ ASIXDevice::Read(uint8 *buffer, size_t *numBytes) USB_FEATURE_ENDPOINT_HALT); if (result != B_OK) { TRACE_ALWAYS("Error during clearing of HALT state:%#010x.\n", - result); + result); return result; } } @@ -213,13 +214,13 @@ ASIXDevice::Read(uint8 *buffer, size_t *numBytes) if (fUseTRXHeader) { if (fActualLengthRead < sizeof(TRXHeader)) { TRACE_ALWAYS("Error: no place for TRXHeader:only %d of %d bytes.\n", - fActualLengthRead, sizeof(TRXHeader)); + fActualLengthRead, sizeof(TRXHeader)); return B_ERROR; // TODO: ??? } if (!header.IsValid()) { TRACE_ALWAYS("Error:TRX Header is invalid: len:%#04x; ilen:%#04x\n", - header.fLength, header.fInvertedLength); + header.fLength, header.fInvertedLength); return B_ERROR; // TODO: ??? } @@ -227,7 +228,7 @@ ASIXDevice::Read(uint8 *buffer, size_t *numBytes) if (fActualLengthRead - sizeof(TRXHeader) > header.Length()) { TRACE_ALWAYS("MISMATCH of the frame length: hdr %d; received:%d\n", - header.Length(), fActualLengthRead - sizeof(TRXHeader)); + header.Length(), fActualLengthRead - sizeof(TRXHeader)); } } else { @@ -248,7 +249,7 @@ ASIXDevice::Write(const uint8 *buffer, size_t *numBytes) if (fRemoved) { TRACE_ALWAYS("Error of writing %d bytes to removed device.\n", - numBytesToWrite); + numBytesToWrite); return B_DEVICE_NOT_FOUND; } @@ -264,7 +265,8 @@ ASIXDevice::Write(const uint8 *buffer, size_t *numBytes) size_t chunkCount = fUseTRXHeader ? 2 : 1 ; status_t result = gUSBModule->queue_bulk_v(fWriteEndpoint, - &txData[startIndex], chunkCount, _WriteCallback, this); + &txData[startIndex], chunkCount, _WriteCallback, this); + if (result != B_OK) { TRACE_ALWAYS("Error of queue_bulk_v request:%#010x\n", result); return result; @@ -380,17 +382,18 @@ ASIXDevice::SetupDevice(bool deviceReplugged) } TRACE("MAC address is:%02x:%02x:%02x:%02x:%02x:%02x\n", - address.ebyte[0], address.ebyte[1], address.ebyte[2], - address.ebyte[3], address.ebyte[4], address.ebyte[5]); + address.ebyte[0], address.ebyte[1], address.ebyte[2], + address.ebyte[3], address.ebyte[4], address.ebyte[5]); if (deviceReplugged) { // this might be the same device that was replugged - read the MAC // address (which should be at the same index) to make sure if (memcmp(&address, &fMACAddress, sizeof(address)) != 0) { TRACE_ALWAYS("Cannot replace device with MAC address:" - "%02x:%02x:%02x:%02x:%02x:%02x\n", - fMACAddress.ebyte[0], fMACAddress.ebyte[1], fMACAddress.ebyte[2], - fMACAddress.ebyte[3], fMACAddress.ebyte[4], fMACAddress.ebyte[5]); + "%02x:%02x:%02x:%02x:%02x:%02x\n", fMACAddress.ebyte[0], + fMACAddress.ebyte[1], fMACAddress.ebyte[2], + fMACAddress.ebyte[3], fMACAddress.ebyte[4], + fMACAddress.ebyte[5]); return B_BAD_VALUE; // is not the same } } else @@ -473,30 +476,26 @@ ASIXDevice::_SetupEndpoints() for (size_t ep = 0; ep < interface->endpoint_count; ep++) { usb_endpoint_descriptor *epd = interface->endpoint[ep].descr; if ((epd->attributes & USB_ENDPOINT_ATTR_MASK) - == USB_ENDPOINT_ATTR_INTERRUPT) - { + == USB_ENDPOINT_ATTR_INTERRUPT) { notifyEndpoint = ep; continue; } if ((epd->attributes & USB_ENDPOINT_ATTR_MASK) - != USB_ENDPOINT_ATTR_BULK) - { + != USB_ENDPOINT_ATTR_BULK) { TRACE_ALWAYS("Error: USB endpoint type %#04x is unknown.\n", - epd->attributes); + epd->attributes); continue; } if ((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) - == USB_ENDPOINT_ADDR_DIR_IN) - { + == USB_ENDPOINT_ADDR_DIR_IN) { readEndpoint = ep; continue; } if ((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_OUT) - == USB_ENDPOINT_ADDR_DIR_OUT) - { + == USB_ENDPOINT_ADDR_DIR_OUT) { writeEndpoint = ep; continue; } @@ -504,16 +503,16 @@ ASIXDevice::_SetupEndpoints() if (notifyEndpoint == -1 || readEndpoint == -1 || writeEndpoint == -1) { TRACE_ALWAYS("Error: not all USB endpoints were found: " - "notify:%d; read:%d; write:%d\n", - notifyEndpoint, readEndpoint, writeEndpoint); + "notify:%d; read:%d; write:%d\n", notifyEndpoint, readEndpoint, + writeEndpoint); return B_ERROR; } gUSBModule->set_configuration(fDevice, config); fNotifyEndpoint = interface->endpoint[notifyEndpoint].handle; - fReadEndpoint = interface->endpoint[readEndpoint ].handle; - fWriteEndpoint = interface->endpoint[writeEndpoint ].handle; + fReadEndpoint = interface->endpoint[readEndpoint].handle; + fWriteEndpoint = interface->endpoint[writeEndpoint].handle; return B_OK; } @@ -524,9 +523,9 @@ ASIXDevice::ReadMACAddress(ether_address_t *address) { size_t actual_length = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, - fReadNodeIDRequest, 0, 0, sizeof(ether_address), - address, &actual_length); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, fReadNodeIDRequest, + 0, 0, sizeof(ether_address), address, &actual_length); + if (result != B_OK) { TRACE_ALWAYS("Error of reading MAC address:%#010x\n", result); return result; @@ -549,14 +548,13 @@ ASIXDevice::ReadRXControlRegister(uint16 *rxcontrol) *rxcontrol = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, - READ_RX_CONTROL, 0, 0, - sizeof(*rxcontrol), rxcontrol, &actual_length); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, READ_RX_CONTROL, + 0, 0, sizeof(*rxcontrol), rxcontrol, &actual_length); if (sizeof(*rxcontrol) != actual_length) { TRACE_ALWAYS("Mismatch during reading RX control register." - "Read %d bytes instead of %d.\n", - actual_length, sizeof(*rxcontrol)); + "Read %d bytes instead of %d.\n", actual_length, + sizeof(*rxcontrol)); } return result; @@ -567,8 +565,8 @@ status_t ASIXDevice::WriteRXControlRegister(uint16 rxcontrol) { status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_RX_CONTROL, rxcontrol, 0, 0, 0, 0); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_RX_CONTROL, + rxcontrol, 0, 0, 0, 0); return result; } @@ -578,9 +576,8 @@ ASIXDevice::StopDevice() { status_t result = WriteRXControlRegister(0); - if (result != B_OK) { + if (result != B_OK) TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", 0, result); - } TRACE_RET(result); return result; @@ -607,7 +604,7 @@ ASIXDevice::SetPromiscuousMode(bool on) if (result != B_OK ) { TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", - rxcontrol, result); + rxcontrol, result); } TRACE_RET(result); @@ -681,9 +678,9 @@ ASIXDevice::ModifyMulticastTable(bool join, ether_address_t* group) // write multicast hash table size_t actualLength = 0; result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_MF_ARRAY, 0, 0, - hashLength, hashTable, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_MF_ARRAY, + 0, 0, hashLength, hashTable, &actualLength); + if (result != B_OK) { TRACE_ALWAYS("Error writing hash table in MAR: %#010x.\n", result); return result; @@ -691,7 +688,7 @@ ASIXDevice::ModifyMulticastTable(bool join, ether_address_t* group) if (actualLength != hashLength) TRACE_ALWAYS("Incomplete writing of hash table: %d bytes of %d\n", - actualLength, hashLength); + actualLength, hashLength); result = WriteRXControlRegister(rxcontrol); if (result != B_OK) diff --git a/src/add-ons/kernel/drivers/network/usb_asix/ASIXVendorRequests.h b/src/add-ons/kernel/drivers/network/usb_asix/ASIXVendorRequests.h index d383368a45..535a60216d 100644 --- a/src/add-ons/kernel/drivers/network/usb_asix/ASIXVendorRequests.h +++ b/src/add-ons/kernel/drivers/network/usb_asix/ASIXVendorRequests.h @@ -66,7 +66,11 @@ enum ASIXRXControl { RXCTL_MULTICAST = 0x0010, RXCTL_AP = 0x0020, // AX88772-178 RXCTL_START = 0x0080, - RXCTL_USB_MFB = 0x0100 // AX88772-178 + RXCTL_USB_MFB_2048 = 0x0000, // AX88772-178 + RXCTL_USB_MFB_4096 = 0x0100, // AX88772-178 + RXCTL_USB_MFB_8192 = 0x0200, // AX88772-178 + RXCTL_USB_MFB_MAX = 0x0300, // aka 16384 + mask AX88772-178 + RXCTL_LOOPBACK = 0x1000, // AX88772A / AX88772B }; diff --git a/src/add-ons/kernel/drivers/network/usb_asix/AX88172Device.cpp b/src/add-ons/kernel/drivers/network/usb_asix/AX88172Device.cpp index 3de0da38ad..a1f9ec95a3 100644 --- a/src/add-ons/kernel/drivers/network/usb_asix/AX88172Device.cpp +++ b/src/add-ons/kernel/drivers/network/usb_asix/AX88172Device.cpp @@ -124,8 +124,8 @@ const uint16 maxFrameSize = 1518; AX88172Device::AX88172Device(usb_device device, DeviceInfo& deviceInfo) - : - ASIXDevice(device, deviceInfo) + : + ASIXDevice(device, deviceInfo) { fStatus = InitDevice(); } @@ -175,8 +175,8 @@ AX88172Device::StartDevice() for (size_t i = 0; i < sizeof(fIPG) / sizeof(fIPG[0]); i++) { status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_IPG0, 0, 0, sizeof(fIPG[i]), &fIPG[i], &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_IPG0, + 0, 0, sizeof(fIPG[i]), &fIPG[i], &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error writing IPG%d: %#010x\n", i, result); @@ -193,7 +193,7 @@ AX88172Device::StartDevice() status_t result = WriteRXControlRegister(rxcontrol); if (result != B_OK) { TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", - rxcontrol, result); + rxcontrol, result); } TRACE_RET(result); @@ -206,7 +206,7 @@ AX88172Device::OnNotify(uint32 actualLength) { if (actualLength < sizeof(AX88172Notify)) { TRACE_ALWAYS("Data underrun error. %d of %d bytes received\n", - actualLength, sizeof(AX88172Notify)); + actualLength, sizeof(AX88172Notify)); return B_BAD_DATA; } @@ -214,7 +214,7 @@ AX88172Device::OnNotify(uint32 actualLength) if (notification->btA1 != 0xa1) { TRACE_ALWAYS("Notify magic byte is invalid: %#02x\n", - notification->btA1); + notification->btA1); } uint phyIndex = 0; @@ -222,11 +222,13 @@ AX88172Device::OnNotify(uint32 actualLength) switch(fMII.ActivePHY()) { case PrimaryPHY: phyIndex = 1; - linkIsUp = (notification->btNN & LINK_STATE_PHY1) == LINK_STATE_PHY1; + linkIsUp = (notification->btNN & LINK_STATE_PHY1) + == LINK_STATE_PHY1; break; case SecondaryPHY: phyIndex = 2; - linkIsUp = (notification->btNN & LINK_STATE_PHY2) == LINK_STATE_PHY2; + linkIsUp = (notification->btNN & LINK_STATE_PHY2) + == LINK_STATE_PHY2; break; default: case CurrentPHY: @@ -239,7 +241,7 @@ AX88172Device::OnNotify(uint32 actualLength) if (linkStateChange) { TRACE("Link state of PHY%d has been changed to '%s'\n", - phyIndex, fHasConnection ? "up" : "down"); + phyIndex, fHasConnection ? "up" : "down"); } if (linkStateChange && fLinkStateChangeSem >= B_OK) @@ -275,15 +277,15 @@ AX88172Device::GetLinkState(ether_link_state *linkState) linkState->media = IFM_ETHER | (fHasConnection ? IFM_ACTIVE : 0); linkState->media |= mediumStatus & (ANLPAR_TX_FD | ANLPAR_10_FD) ? - IFM_FULL_DUPLEX : IFM_HALF_DUPLEX; + IFM_FULL_DUPLEX : IFM_HALF_DUPLEX; linkState->speed = mediumStatus & (ANLPAR_TX_FD | ANLPAR_TX_HD) - ? 100000000 : 10000000; + ? 100000000 : 10000000; TRACE_FLOW("Medium state: %s, %lld MBit/s, %s duplex.\n", - (linkState->media & IFM_ACTIVE) ? "active" : "inactive", - linkState->speed / 1000000, - (linkState->media & IFM_FULL_DUPLEX) ? "full" : "half"); + (linkState->media & IFM_ACTIVE) ? "active" : "inactive", + linkState->speed / 1000000, + (linkState->media & IFM_FULL_DUPLEX) ? "full" : "half"); return B_OK; } diff --git a/src/add-ons/kernel/drivers/network/usb_asix/AX88178Device.cpp b/src/add-ons/kernel/drivers/network/usb_asix/AX88178Device.cpp index 092e7e04a7..99959d76a5 100644 --- a/src/add-ons/kernel/drivers/network/usb_asix/AX88178Device.cpp +++ b/src/add-ons/kernel/drivers/network/usb_asix/AX88178Device.cpp @@ -158,8 +158,8 @@ const uint16 maxFrameSize = 1536; AX88178Device::AX88178Device(usb_device device, DeviceInfo& deviceInfo) - : - ASIXDevice(device, deviceInfo) + : + ASIXDevice(device, deviceInfo) { fStatus = InitDevice(); } @@ -202,8 +202,8 @@ AX88178Device::SetupDevice(bool deviceReplugged) size_t actualLength = 0; // get the "magic" word from EEPROM result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_SROM_ENABLE, 0, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_SROM_ENABLE, + 0, 0, 0, 0, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of enabling SROM access:%#010x\n", result); @@ -212,9 +212,8 @@ AX88178Device::SetupDevice(bool deviceReplugged) uint16 eepromData = 0; status_t op_result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, - READ_SROM, 0x17, 0, - sizeof(eepromData), &eepromData, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, READ_SROM, + 0x17, 0, sizeof(eepromData), &eepromData, &actualLength); if (op_result != B_OK) { TRACE_ALWAYS("Error of reading SROM data:%#010x\n", result); @@ -222,13 +221,12 @@ AX88178Device::SetupDevice(bool deviceReplugged) if (actualLength != sizeof(eepromData)) { TRACE_ALWAYS("Mismatch of reading SROM data." - "Read %d bytes instead of %d\n", - actualLength, sizeof(eepromData)); + "Read %d bytes instead of %d\n", actualLength, sizeof(eepromData)); } result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_SROM_DISABLE, 0, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_SROM_DISABLE, + 0, 0, 0, 0, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of disabling SROM access: %#010x\n", result); @@ -261,15 +259,14 @@ AX88178Device::SetupDevice(bool deviceReplugged) for (size_t i = from; i <= to; i++) { result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_GPIOS, GPIOCommands[i].value, - 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_GPIOS, + GPIOCommands[i].value, 0, 0, 0, &actualLength); snooze(GPIOCommands[i].delay); if (result != B_OK) { TRACE_ALWAYS("Error of GPIO setup command %d:[%#04x]: %#010x\n", - i, GPIOCommands[i].value, result); + i, GPIOCommands[i].value, result); return result; } } @@ -277,8 +274,8 @@ AX88178Device::SetupDevice(bool deviceReplugged) uint8 uSWReset = 0; // finally a bit of exercises for SW reset register... result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_SOFT_RESET, uSWReset, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_SOFT_RESET, + uSWReset, 0, 0, 0, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of SW reset to %#02x: %#010x\n", uSWReset, result); @@ -289,8 +286,8 @@ AX88178Device::SetupDevice(bool deviceReplugged) uSWReset = SW_RESET_PRL | SW_RESET_BIT6; result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_SOFT_RESET, uSWReset, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_SOFT_RESET, + uSWReset, 0, 0, 0, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of SW reset to %#02x: %#010x\n", uSWReset, result); @@ -317,8 +314,8 @@ AX88178Device::StartDevice() { size_t actualLength = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_IPGS, 0, 0, sizeof(fIPG), fIPG, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_IPGS, + 0, 0, sizeof(fIPG), fIPG, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of writing IPGs:%#010x\n", result); @@ -327,14 +324,14 @@ AX88178Device::StartDevice() if (actualLength != sizeof(fIPG)) { TRACE_ALWAYS("Mismatch of written IPGs data. " - "%d bytes of %d written.\n", actualLength, sizeof(fIPG)); + "%d bytes of %d written.\n", actualLength, sizeof(fIPG)); } uint16 rxcontrol = RXCTL_START | RXCTL_BROADCAST; result = WriteRXControlRegister(rxcontrol); if (result != B_OK) { TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", - rxcontrol, result); + rxcontrol, result); } TRACE_RET(result); @@ -347,7 +344,7 @@ AX88178Device::OnNotify(uint32 actualLength) { if (actualLength < sizeof(AX88178_Notify)) { TRACE_ALWAYS("Data underrun error. %d of %d bytes received\n", - actualLength, sizeof(AX88178_Notify)); + actualLength, sizeof(AX88178_Notify)); return B_BAD_DATA; } @@ -355,7 +352,7 @@ AX88178Device::OnNotify(uint32 actualLength) if (notification->btA1 != 0xa1) { TRACE_ALWAYS("Notify magic byte is invalid: %#02x\n", - notification->btA1); + notification->btA1); } uint phyIndex = 0; @@ -363,11 +360,13 @@ AX88178Device::OnNotify(uint32 actualLength) switch(fMII.ActivePHY()) { case PrimaryPHY: phyIndex = 1; - linkIsUp = (notification->btBB & LINK_STATE_PPLS) == LINK_STATE_PPLS; + linkIsUp = (notification->btBB & LINK_STATE_PPLS) + == LINK_STATE_PPLS; break; case SecondaryPHY: phyIndex = 2; - linkIsUp = (notification->btBB & LINK_STATE_SPLS) == LINK_STATE_SPLS; + linkIsUp = (notification->btBB & LINK_STATE_SPLS) + == LINK_STATE_SPLS; break; default: case CurrentPHY: @@ -380,7 +379,7 @@ AX88178Device::OnNotify(uint32 actualLength) if (linkStateChange) { TRACE("Link state of PHY%d has been changed to '%s'\n", - phyIndex, fHasConnection ? "up" : "down"); + phyIndex, fHasConnection ? "up" : "down"); } if (linkStateChange && fLinkStateChangeSem >= B_OK) @@ -396,9 +395,8 @@ AX88178Device::GetLinkState(ether_link_state *linkState) size_t actualLength = 0; uint16 mediumStatus = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, - READ_MEDIUM_STATUS, 0, 0, sizeof(mediumStatus), - &mediumStatus, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, READ_MEDIUM_STATUS, + 0, 0, sizeof(mediumStatus), &mediumStatus, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of reading medium status:%#010x.\n", result); @@ -415,19 +413,19 @@ AX88178Device::GetLinkState(ether_link_state *linkState) linkState->quality = 1000; - linkState->media = IFM_ETHER | (fHasConnection ? IFM_ACTIVE : 0); - linkState->media |= (mediumStatus & MEDIUM_STATE_FD) ? - IFM_FULL_DUPLEX : IFM_HALF_DUPLEX; + linkState->media = IFM_ETHER | (fHasConnection ? IFM_ACTIVE : 0); + linkState->media |= (mediumStatus & MEDIUM_STATE_FD) ? + IFM_FULL_DUPLEX : IFM_HALF_DUPLEX; - linkState->speed = (mediumStatus & MEDIUM_STATE_PS_100) - ? 100000000 : 10000000; - linkState->speed = (mediumStatus & MEDIUM_STATE_GM) ? - 1000000000 : linkState->speed; + linkState->speed = (mediumStatus & MEDIUM_STATE_PS_100) + ? 100000000 : 10000000; + linkState->speed = (mediumStatus & MEDIUM_STATE_GM) ? + 1000000000 : linkState->speed; TRACE_FLOW("Medium state: %s, %lld MBit/s, %s duplex.\n", - (linkState->media & IFM_ACTIVE) ? "active" : "inactive", - linkState->speed / 1000000, - (linkState->media & IFM_FULL_DUPLEX) ? "full" : "half"); + (linkState->media & IFM_ACTIVE) ? "active" : "inactive", + linkState->speed / 1000000, + (linkState->media & IFM_FULL_DUPLEX) ? "full" : "half"); return B_OK; } diff --git a/src/add-ons/kernel/drivers/network/usb_asix/AX88772Device.cpp b/src/add-ons/kernel/drivers/network/usb_asix/AX88772Device.cpp index 8bb1e4b9a7..d05980337a 100644 --- a/src/add-ons/kernel/drivers/network/usb_asix/AX88772Device.cpp +++ b/src/add-ons/kernel/drivers/network/usb_asix/AX88772Device.cpp @@ -157,9 +157,18 @@ enum AX88772_BBState { LINK_STATE_MDINT = 0x08 }; +// RX Control Register bits (772B) +enum ASIX772RXControl { + RXCTL_HDR_TYPE_0 = 0x0000, + RXCTL_HDR_TYPE_1 = 0x0100, + RXCTL_HDR_IPALIGN = 0x0200, + RXCTL_ADD_CHKSUM = 0x0400, +}; + // EEPROM Map. enum AX88772B_EEPROM { - EEPROM_772B_NODE_ID = 0x04 + EEPROM_772B_NODE_ID = 0x04, + EEPROM_772B_PHY_PWRCFG = 0x18 }; enum AX88772B_MFB { @@ -194,8 +203,8 @@ const uint16 maxFrameSize = 1536; AX88772Device::AX88772Device(usb_device device, DeviceInfo& deviceInfo) - : - ASIXDevice(device, deviceInfo) + : + ASIXDevice(device, deviceInfo) { fStatus = InitDevice(); } @@ -281,12 +290,10 @@ AX88772Device::SetupDevice(bool deviceReplugged) size_t actualLength = 0; result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_MEDIUM_MODE, - MEDIUM_STATE_FD | MEDIUM_STATE_BIT2 | - MEDIUM_STATE_RFC| MEDIUM_STATE_TFC | - MEDIUM_STATE_RE | MEDIUM_STATE_PS_100, - 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_MEDIUM_MODE, + MEDIUM_STATE_FD | MEDIUM_STATE_BIT2 | MEDIUM_STATE_RFC + | MEDIUM_STATE_TFC | MEDIUM_STATE_RE | MEDIUM_STATE_PS_100, + 0, 0, 0, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of setting medium mode: %#010x\n", result); @@ -304,8 +311,8 @@ AX88772Device::_SetupAX88772() // enable GPIO2 - magic from FreeBSD's if_axe uint16 GPIOs = GPIO_OO_2EN | GPIO_IO_2 | GPIO_RSE; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_GPIOS, GPIOs, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_GPIOS, + GPIOs, 0, 0, 0, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of wrinting GPIOs: %#010x\n", result); @@ -314,16 +321,16 @@ AX88772Device::_SetupAX88772() // select PHY bool useEmbeddedPHY = fMII.PHYID() == PHYIDEmbedded; - uint16 selectPHY = useEmbeddedPHY ? - SW_PHY_SEL_STATUS_INT : SW_PHY_SEL_STATUS_EXT; + uint16 selectPHY = useEmbeddedPHY + ? SW_PHY_SEL_STATUS_INT : SW_PHY_SEL_STATUS_EXT; result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_PHY_SEL, selectPHY, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, + WRITE_PHY_SEL, selectPHY, 0, 0, 0, &actualLength); snooze(10000); TRACE("Selecting %s PHY[%#02x].\n", - useEmbeddedPHY ? "embedded" : "external", selectPHY); + useEmbeddedPHY ? "embedded" : "external", selectPHY); if (result != B_OK) { TRACE_ALWAYS("Error of selecting PHY:%#010x\n", result); @@ -353,15 +360,14 @@ AX88772Device::_SetupAX88772() for (size_t i = from; i <= to; i++) { result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_SOFT_RESET, resetCommands[i].reset, - 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_SOFT_RESET, + resetCommands[i].reset, 0, 0, 0, &actualLength); snooze(resetCommands[i].delay); if (result != B_OK) { TRACE_ALWAYS("Error of SW reset command %d:[%#04x]: %#010x\n", - i, resetCommands[i].reset, result); + i, resetCommands[i].reset, result); return result; } } @@ -377,19 +383,19 @@ AX88772Device::_WakeupPHY() { // select PHY bool useEmbeddedPHY = fMII.PHYID() == PHYIDEmbedded; - uint16 selectPHY = useEmbeddedPHY ? - SW_PHY_SEL_STATUS_INT : SW_PHY_SEL_STATUS_EXT; + uint16 selectPHY = useEmbeddedPHY + ? SW_PHY_SEL_STATUS_INT : SW_PHY_SEL_STATUS_EXT; selectPHY |= SW_PHY_SEL_STATUS_SS_MII | SW_PHY_SEL_STATUS_SS_ENB; size_t actualLength = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_PHY_SEL, selectPHY, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_PHY_SEL, + selectPHY, 0, 0, 0, &actualLength); snooze(31000); TRACE("Selecting %s PHY[%#02x].\n", - useEmbeddedPHY ? "embedded" : "external", selectPHY); + useEmbeddedPHY ? "embedded" : "external", selectPHY); if (result != B_OK) { TRACE_ALWAYS("Error of selecting PHY:%#010x\n", result); @@ -408,15 +414,14 @@ AX88772Device::_WakeupPHY() for (size_t i = 0; i < _countof(resetCommands); i++) { result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_SOFT_RESET, resetCommands[i].reset, - 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_SOFT_RESET, + resetCommands[i].reset, 0, 0, 0, &actualLength); snooze(resetCommands[i].delay); if (result != B_OK) { TRACE_ALWAYS("Error of SW reset command %d:[%#04x]: %#010x\n", - i, resetCommands[i].reset, result); + i, resetCommands[i].reset, result); return result; } } @@ -431,8 +436,8 @@ AX88772Device::_SetupAX88772A() // Reload EEPROM size_t actualLength = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_GPIOS, GPIO_RSE, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_GPIOS, + GPIO_RSE, 0, 0, 0, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of reloading EEPROM: %#010x\n", result); @@ -457,8 +462,8 @@ AX88772Device::_SetupAX88772B() // Reload EEPROM size_t actualLength = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_GPIOS, GPIO_RSE, 0, 0, 0, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_GPIOS, + GPIO_RSE, 0, 0, 0, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of reloading EEPROM: %#010x\n", result); @@ -482,8 +487,8 @@ AX88772Device::StartDevice() { size_t actualLength = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, - WRITE_IPGS, 0, 0, sizeof(fIPG), fIPG, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT, WRITE_IPGS, + 0, 0, sizeof(fIPG), fIPG, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of writing IPGs:%#010x\n", result); @@ -492,12 +497,12 @@ AX88772Device::StartDevice() if (actualLength != sizeof(fIPG)) { TRACE_ALWAYS("Mismatch of written IPGs data. " - "%d bytes of %d written.\n", actualLength, sizeof(fIPG)); + "%d bytes of %d written.\n", actualLength, sizeof(fIPG)); } - + uint16 rxcontrol = 0; - + // AX88772B uses different maximum frame burst configuration. if (fDeviceInfo.fType == DeviceInfo::AX88772B) { result = gUSBModule->send_request(fDevice, @@ -511,8 +516,11 @@ AX88772Device::StartDevice() TRACE_ALWAYS("Error of writing frame burst:%#010x\n", result); return result; } - - rxcontrol = RXCTL_USB_MFB; + rxcontrol = RXCTL_HDR_TYPE_1; + } else { + // TODO: FreeBSD documents this to speed up xfers, I don't + // have the hardware to test however. + // rxcontrol = RXCTL_USB_MFB_MAX; } rxcontrol |= RXCTL_START | RXCTL_BROADCAST; @@ -532,15 +540,15 @@ AX88772Device::OnNotify(uint32 actualLength) { if (actualLength < sizeof(AX88772_Notify)) { TRACE_ALWAYS("Data underrun error. %d of %d bytes received\n", - actualLength, sizeof(AX88772_Notify)); + actualLength, sizeof(AX88772_Notify)); return B_BAD_DATA; } - AX88772_Notify *notification = (AX88772_Notify *)fNotifyBuffer; + AX88772_Notify *notification = (AX88772_Notify *)fNotifyBuffer; if (notification->btA1 != 0xa1) { TRACE_ALWAYS("Notify magic byte is invalid: %#02x\n", - notification->btA1); + notification->btA1); } uint phyIndex = 0; @@ -548,11 +556,13 @@ AX88772Device::OnNotify(uint32 actualLength) switch(fMII.ActivePHY()) { case PrimaryPHY: phyIndex = 1; - linkIsUp = (notification->btBB & LINK_STATE_PPLS) == LINK_STATE_PPLS; + linkIsUp = (notification->btBB & LINK_STATE_PPLS) + == LINK_STATE_PPLS; break; case SecondaryPHY: phyIndex = 2; - linkIsUp = (notification->btBB & LINK_STATE_SPLS) == LINK_STATE_SPLS; + linkIsUp = (notification->btBB & LINK_STATE_SPLS) + == LINK_STATE_SPLS; break; default: case CurrentPHY: @@ -565,7 +575,7 @@ AX88772Device::OnNotify(uint32 actualLength) if (linkStateChange) { TRACE("Link state of PHY%d has been changed to '%s'\n", - phyIndex, fHasConnection ? "up" : "down"); + phyIndex, fHasConnection ? "up" : "down"); } if (linkStateChange && fLinkStateChangeSem >= B_OK) @@ -581,9 +591,8 @@ AX88772Device::GetLinkState(ether_link_state *linkState) size_t actualLength = 0; uint16 mediumStatus = 0; status_t result = gUSBModule->send_request(fDevice, - USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, - READ_MEDIUM_STATUS, 0, 0, sizeof(mediumStatus), - &mediumStatus, &actualLength); + USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN, READ_MEDIUM_STATUS, + 0, 0, sizeof(mediumStatus), &mediumStatus, &actualLength); if (result != B_OK) { TRACE_ALWAYS("Error of reading medium status:%#010x.\n", result); @@ -592,25 +601,25 @@ AX88772Device::GetLinkState(ether_link_state *linkState) if (actualLength != sizeof(mediumStatus)) { TRACE_ALWAYS("Mismatch of reading medium status." - "Read %d bytes instead of %d\n", - actualLength, sizeof(mediumStatus)); + "Read %d bytes instead of %d\n", actualLength, + sizeof(mediumStatus)); } TRACE_FLOW("Medium status is %#04x\n", mediumStatus); linkState->quality = 1000; - linkState->media = IFM_ETHER | (fHasConnection ? IFM_ACTIVE : 0); - linkState->media |= (mediumStatus & MEDIUM_STATE_FD) ? - IFM_FULL_DUPLEX : IFM_HALF_DUPLEX; + linkState->media = IFM_ETHER | (fHasConnection ? IFM_ACTIVE : 0); + linkState->media |= (mediumStatus & MEDIUM_STATE_FD) ? + IFM_FULL_DUPLEX : IFM_HALF_DUPLEX; - linkState->speed = (mediumStatus & MEDIUM_STATE_PS_100) - ? 100000000 : 10000000; + linkState->speed = (mediumStatus & MEDIUM_STATE_PS_100) + ? 100000000 : 10000000; TRACE_FLOW("Medium state: %s, %lld MBit/s, %s duplex.\n", - (linkState->media & IFM_ACTIVE) ? "active" : "inactive", - linkState->speed / 1000000, - (linkState->media & IFM_FULL_DUPLEX) ? "full" : "half"); + (linkState->media & IFM_ACTIVE) ? "active" : "inactive", + linkState->speed / 1000000, + (linkState->media & IFM_FULL_DUPLEX) ? "full" : "half"); return B_OK; } diff --git a/src/add-ons/kernel/drivers/network/usb_asix/Driver.cpp b/src/add-ons/kernel/drivers/network/usb_asix/Driver.cpp index b7aa8e687b..2d4bc4b10d 100644 --- a/src/add-ons/kernel/drivers/network/usb_asix/Driver.cpp +++ b/src/add-ons/kernel/drivers/network/usb_asix/Driver.cpp @@ -56,6 +56,7 @@ DeviceInfo gSupportedDevices[] = { { { 0x0b95, 0x772a }, DeviceInfo::AX88772A, "AX88772A 10/100" }, { { 0x0b95, 0x772b }, DeviceInfo::AX88772B, "AX88772B 10/100" }, { { 0x0b95, 0x7e2b }, DeviceInfo::AX88772B, "AX88772B 10/100" }, + { { 0x0df6, 0x0056 }, DeviceInfo::AX88178, "Sitecom LN-031" }, { { 0x0df6, 0x061c }, DeviceInfo::AX88178, "Sitecom LN-028" }, { { 0x1189, 0x0893 }, DeviceInfo::AX88172, "Acer C&M EP-1427X-2" }, { { 0x13b1, 0x0018 }, DeviceInfo::AX88772A, "Linksys USB200M rev.2" }, @@ -63,9 +64,10 @@ DeviceInfo gSupportedDevices[] = { { { 0x1557, 0x7720 }, DeviceInfo::AX88772, "OQO 01+ Ethernet" }, { { 0x1631, 0x6200 }, DeviceInfo::AX88172, "GoodWay USB2Ethernet" }, { { 0x1737, 0x0039 }, DeviceInfo::AX88178, "LinkSys 1000" }, + { { 0x17ef, 0x7203 }, DeviceInfo::AX88772, "Lenovo U2L100P 10/100" }, { { 0x2001, 0x1A00 }, DeviceInfo::AX88172, "D-Link DUB-E100" }, { { 0x2001, 0x3c05 }, DeviceInfo::AX88772, "D-Link DUB-E100 rev.B1" }, - { { 0x6189, 0x182d }, DeviceInfo::AX88172, "Sitecom LN-029" } + { { 0x6189, 0x182d }, DeviceInfo::AX88172, "Sitecom LN-029" }, }; diff --git a/src/add-ons/kernel/file_systems/nfs4/Connection.cpp b/src/add-ons/kernel/file_systems/nfs4/Connection.cpp index 5994b51eee..2fa044d3f7 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Connection.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Connection.cpp @@ -16,8 +16,9 @@ #include #include -#include #include +#include +#include #define NFS4_PORT 2049 @@ -655,7 +656,7 @@ Connection::Connect() PeerAddress address(fPeerAddress.Family()); do { - port = rand() % (IPPORT_RESERVED - NFS_MIN_PORT); + port = get_random() % (IPPORT_RESERVED - NFS_MIN_PORT); port += NFS_MIN_PORT; if (attempt == 9) diff --git a/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp b/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp index 2fce4fde6c..086a2a4655 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp @@ -40,6 +40,7 @@ Delegation::GiveUp(bool truncate) status_t Delegation::ReturnDelegation() { + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -54,8 +55,10 @@ Delegation::ReturnDelegation() ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv, NULL, fInode->GetOpenState())) + if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, + fInode->GetOpenState())) { continue; + } reply.PutFH(); diff --git a/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp b/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp index d620481c77..45f002d202 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp @@ -148,8 +148,12 @@ FileInfo::UpdateFileHandles(FileSystem* fs) uint32 i; InodeNames* names = fNames; - for (i = 0; names != NULL; i++) + for (i = 0; names != NULL; i++) { + if (names->fNames.IsEmpty()) + return B_ENTRY_NOT_FOUND; + names = names->fNames.Head()->fParent; + } if (i > 0) { names = fNames; diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp index c1a5a7b9ad..184e79a373 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp @@ -13,6 +13,7 @@ #include #include +#include #include "Request.h" #include "RootInode.h" @@ -32,9 +33,7 @@ FileSystem::FileSystem(const MountConfiguration& configuration) fId(1), fConfiguration(configuration) { - fOpenOwner = rand(); - fOpenOwner <<= 32; - fOpenOwner |= rand(); + fOpenOwner = get_random(); mutex_init(&fOpenOwnerLock, NULL); mutex_init(&fOpenLock, NULL); diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index 6afceaafc1..be69f682c1 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -60,6 +60,7 @@ Inode::CreateInode(FileSystem* fs, const FileInfo& fi, Inode** _inode) inode->fInfo = fi; inode->fFileSystem = fs; + uint32 attempt = 0; uint64 size; do { RPC::Server* serv = fs->Server(); @@ -78,7 +79,7 @@ Inode::CreateInode(FileSystem* fs, const FileInfo& fi, Inode** _inode) ReplyInterpreter& reply = request.Reply(); - if (inode->HandleErrors(reply.NFS4Error(), serv)) + if (inode->HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -109,6 +110,7 @@ Inode::CreateInode(FileSystem* fs, const FileInfo& fi, Inode** _inode) // FATTR4_SIZE is mandatory size = values[2].fData.fValue64; + inode->fMaxFileSize = size; // FATTR4_FSID is mandatory FileSystemId* fsid @@ -169,14 +171,15 @@ Inode::RevalidateFileCache() if (change == fChange) return B_OK; + SyncAndCommit(true); + file_cache_delete(fFileCache); + struct stat st; + fMetaCache.InvalidateStat(); result = Stat(&st); if (result != B_OK) return result; - SyncAndCommit(true); - file_cache_delete(fFileCache); - fFileCache = file_cache_create(fFileSystem->DevId(), ID(), st.st_size); change = fChange; @@ -599,6 +602,9 @@ Inode::WriteStat(const struct stat* st, uint32 mask, OpenAttrCookie* cookie) uint32 i = 0; if ((mask & B_STAT_SIZE) != 0) { + fMaxFileSize = st->st_size; + file_cache_set_size(fFileCache, st->st_size); + attr[i].fAttribute = FATTR4_SIZE; attr[i].fFreePointer = false; attr[i].fData.fValue64 = st->st_size; diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp index 0ea69d0685..eef37a619a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp @@ -146,6 +146,7 @@ Inode::ReadDirUp(struct dirent* de, uint32 pos, uint32 size) { ASSERT(de != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -166,7 +167,7 @@ Inode::ReadDirUp(struct dirent* de, uint32 pos, uint32 size) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp index d61907429d..a343f7c60d 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp @@ -410,26 +410,29 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer, ASSERT(_buffer != NULL); ASSERT(_length != NULL); - struct stat st; - status_t result = Stat(&st); - if (result != B_OK) - return result; + if (pos < 0) + pos = 0; + + if ((cookie->fMode & O_RWMASK) == O_RDONLY) + return B_NOT_ALLOWED; if ((cookie->fMode & O_APPEND) != 0) - pos = st.st_size; + pos = fMaxFileSize; - uint64 fileSize = max_c(st.st_size, pos + *_length); - fMaxFileSize = max_c(fMaxFileSize, fileSize); + uint64 fileSize = max_c((off_t)fMaxFileSize, pos + *_length); + if (fileSize > fMaxFileSize) { + status_t result = file_cache_set_size(fFileCache, fileSize); + if (result != B_OK) + return result; + fMaxFileSize = fileSize; + fMetaCache.GrowFile(fMaxFileSize); + } if ((cookie->fMode & O_NOCACHE) != 0) { WriteDirect(cookie, pos, _buffer, _length); Commit(); } - result = file_cache_set_size(fFileCache, fileSize); - if (result != B_OK) - return result; - return file_cache_write(fFileCache, cookie, pos, _buffer, _length); } diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h index aab14e6596..d0d25142b4 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h @@ -367,5 +367,13 @@ sSecToBigTime(uint32 sec) } +static inline bool +IsFileHandleInvalid(uint32 error) +{ + return error == NFS4ERR_BADHANDLE || error == NFS4ERR_FHEXPIRED + || error == NFS4ERR_STALE; +} + + #endif // NFS4DEFS_H diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp index a3519792ef..af9b47d07d 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp @@ -20,6 +20,7 @@ NFS4Inode::GetChangeInfo(uint64* change, bool attrDir) { ASSERT(change != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -39,7 +40,7 @@ NFS4Inode::GetChangeInfo(uint64* change, bool attrDir) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -62,6 +63,7 @@ NFS4Inode::GetChangeInfo(uint64* change, bool attrDir) status_t NFS4Inode::CommitWrites() { + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -76,7 +78,7 @@ NFS4Inode::CommitWrites() ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -90,6 +92,7 @@ NFS4Inode::Access(uint32* allowed) { ASSERT(allowed != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -104,7 +107,7 @@ NFS4Inode::Access(uint32* allowed) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -120,6 +123,7 @@ NFS4Inode::LookUp(const char* name, uint64* change, uint64* fileID, { ASSERT(name != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -150,7 +154,7 @@ NFS4Inode::LookUp(const char* name, uint64* change, uint64* fileID, ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -209,6 +213,7 @@ NFS4Inode::Link(Inode* dir, const char* name, ChangeInfo* changeInfo) ASSERT(name != NULL); ASSERT(changeInfo != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -225,7 +230,7 @@ NFS4Inode::Link(Inode* dir, const char* name, ChangeInfo* changeInfo) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -244,6 +249,7 @@ NFS4Inode::ReadLink(void* buffer, size_t* length) ASSERT(buffer != NULL); ASSERT(length != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -258,7 +264,7 @@ NFS4Inode::ReadLink(void* buffer, size_t* length) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -278,6 +284,7 @@ NFS4Inode::GetStat(AttrValue** values, uint32* count, OpenAttrCookie* cookie) ASSERT(values != NULL); ASSERT(count != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -300,7 +307,7 @@ NFS4Inode::GetStat(AttrValue** values, uint32* count, OpenAttrCookie* cookie) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -315,6 +322,7 @@ NFS4Inode::WriteStat(OpenState* state, AttrValue* attrs, uint32 attrCount) { ASSERT(attrs != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -334,7 +342,7 @@ NFS4Inode::WriteStat(OpenState* state, AttrValue* attrs, uint32 attrCount) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -360,9 +368,10 @@ NFS4Inode::RenameNode(Inode* from, Inode* to, const char* fromName, ASSERT(fromChange != NULL); ASSERT(toChange != NULL); + uint32 attempt = 0; do { - RPC::Server* serv = from->fFileSystem->Server(); - Request request(serv, from->fFileSystem); + RPC::Server* server = from->fFileSystem->Server(); + Request request(server, from->fFileSystem); RequestBuilder& req = request.Builder(); if (attribute) @@ -388,24 +397,14 @@ NFS4Inode::RenameNode(Inode* from, Inode* to, const char* fromName, ReplyInterpreter& reply = request.Reply(); - // FileHandle has expired - if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) { - from->fInfo.UpdateFileHandles(from->fFileSystem); - to->fInfo.UpdateFileHandles(to->fFileSystem); + // If we have to wait, migrate to another server, etc then the first + // HandleErrors() will do that. However, if the file handles + // were invalid then we need to update both Inodes. + bool retry = from->HandleErrors(attempt, reply.NFS4Error(), server); + if (IsFileHandleInvalid(reply.NFS4Error())) + retry |= to->HandleErrors(attempt, reply.NFS4Error(), server); + if (retry) continue; - } - - // filesystem has been moved - if (reply.NFS4Error() == NFS4ERR_MOVED) { - from->fFileSystem->Migrate(serv); - continue; - } - - // need to wait - if (reply.NFS4Error() == NFS4ERR_DELAY) { - snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT); - continue; - } reply.PutFH(); reply.SaveFH(); @@ -455,6 +454,7 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms, OpenState* state, bool confirm; status_t result; + uint32 attempt = 0; uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); do { state->fClientID = fFileSystem->NFSServer()->ClientId(); @@ -497,12 +497,14 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms, OpenState* state, ReplyInterpreter& reply = request.Reply(); - sequence += IncrementSequence(reply.NFS4Error()); + result = reply.PutFH(); + if (result == B_OK) + sequence += IncrementSequence(reply.NFS4Error()); - if (HandleErrors(reply.NFS4Error(), serv, NULL, state, &sequence)) + if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, state, + &sequence)) { continue; - - reply.PutFH(); + } result = reply.Open(state->fStateID, &state->fStateSeq, &confirm, delegation, changeInfo); @@ -549,6 +551,8 @@ NFS4Inode::OpenFile(OpenState* state, int mode, OpenDelegationData* delegation) bool confirm; status_t result; + + uint32 attempt = 0; uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); do { state->fClientID = fFileSystem->NFSServer()->ClientId(); @@ -592,11 +596,6 @@ NFS4Inode::OpenFile(OpenState* state, int mode, OpenDelegationData* delegation) ReplyInterpreter& reply = request.Reply(); - sequence += IncrementSequence(reply.NFS4Error()); - - if (HandleErrors(reply.NFS4Error(), serv, NULL, state, &sequence)) - continue; - // Verify if the file we want to open is the file this Inode // represents. if (fFileSystem->IsAttrSupported(FATTR4_FILEID) @@ -609,16 +608,21 @@ NFS4Inode::OpenFile(OpenState* state, int mode, OpenDelegationData* delegation) } result = reply.Verify(); - if (result != B_OK) + if (result != B_OK && reply.NFS4Error() == NFS4ERR_NOT_SAME) { fFileSystem->OpenOwnerSequenceUnlock(sequence); - - if (result != B_OK && reply.NFS4Error() == NFS4ERR_NOT_SAME) return B_ENTRY_NOT_FOUND; - else if (result != B_OK) - return result; + } + } + + result = reply.PutFH(); + if (result == B_OK) + sequence += IncrementSequence(reply.NFS4Error()); + + if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, state, + &sequence)) { + continue; } - reply.PutFH(); result = reply.Open(state->fStateID, &state->fStateSeq, &confirm, delegation); if (result != B_OK) { @@ -656,6 +660,8 @@ NFS4Inode::OpenAttr(OpenState* state, const char* name, int mode, bool confirm; status_t result; + + uint32 attempt = 0; uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); do { state->fClientID = fFileSystem->NFSServer()->ClientId(); @@ -678,12 +684,15 @@ NFS4Inode::OpenAttr(OpenState* state, const char* name, int mode, ReplyInterpreter& reply = request.Reply(); - sequence += IncrementSequence(reply.NFS4Error()); + result = reply.PutFH(); + if (result == B_OK) + sequence += IncrementSequence(reply.NFS4Error()); - if (HandleErrors(reply.NFS4Error(), serv, NULL, state, &sequence)) + if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, state, + &sequence)) { continue; + } - reply.PutFH(); result = reply.Open(state->fStateID, &state->fStateSeq, &confirm, delegation); @@ -716,6 +725,7 @@ NFS4Inode::ReadFile(OpenStateCookie* cookie, OpenState* state, uint64 position, ASSERT(buffer != NULL); ASSERT(eof != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -730,7 +740,7 @@ NFS4Inode::ReadFile(OpenStateCookie* cookie, OpenState* state, uint64 position, ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv, cookie, state)) + if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie, state)) continue; reply.PutFH(); @@ -751,6 +761,7 @@ NFS4Inode::WriteFile(OpenStateCookie* cookie, OpenState* state, uint64 position, ASSERT(length != NULL); ASSERT(buffer != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -767,7 +778,7 @@ NFS4Inode::WriteFile(OpenStateCookie* cookie, OpenState* state, uint64 position, ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv, cookie, state)) + if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie, state)) continue; reply.PutFH(); @@ -790,6 +801,7 @@ NFS4Inode::CreateObject(const char* name, const char* path, int mode, ASSERT(changeInfo != NULL); ASSERT(handle != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -829,7 +841,7 @@ NFS4Inode::CreateObject(const char* name, const char* path, int mode, ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -869,6 +881,7 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo, ASSERT(name != NULL); ASSERT(changeInfo != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -899,7 +912,7 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo, ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -949,6 +962,7 @@ NFS4Inode::ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie, ASSERT(count != NULL); ASSERT(eof != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -975,7 +989,7 @@ NFS4Inode::ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie, ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -1022,6 +1036,7 @@ NFS4Inode::OpenAttrDir(FileHandle* handle) { ASSERT(handle != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -1037,7 +1052,7 @@ NFS4Inode::OpenAttrDir(FileHandle* handle) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(attempt, reply.NFS4Error(), serv)) continue; reply.PutFH(); @@ -1059,6 +1074,7 @@ NFS4Inode::TestLock(OpenFileCookie* cookie, LockType* type, uint64* position, ASSERT(position != NULL); ASSERT(length != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -1072,8 +1088,10 @@ NFS4Inode::TestLock(OpenFileCookie* cookie, LockType* type, uint64* position, return result; ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv, cookie)) - continue; + if (reply.NFS4Error() != NFS4ERR_DENIED) { + if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie)) + continue; + } reply.PutFH(); result = reply.LockT(position, length, type); @@ -1096,6 +1114,7 @@ NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait) ASSERT(cookie != NULL); ASSERT(lockInfo != NULL); + uint32 attempt = 0; uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); do { MutexLocker ownerLocker(lockInfo->fOwner->fLock); @@ -1115,21 +1134,20 @@ NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait) ReplyInterpreter& reply = request.Reply(); - sequence += IncrementSequence(reply.NFS4Error()); + result = reply.PutFH(); + if (result == B_OK) + sequence += IncrementSequence(reply.NFS4Error()); - reply.PutFH(); result = reply.Lock(lockInfo); ownerLocker.Unlock(); - if (wait && reply.NFS4Error() == NFS4ERR_DENIED) { - fFileSystem->OpenOwnerSequenceUnlock(sequence); - snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE, - B_RELATIVE_TIMEOUT); - sequence = fFileSystem->OpenOwnerSequenceLock(); - continue; + + if (reply.NFS4Error() != NFS4ERR_DENIED || wait) { + if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie, NULL, + &sequence)) { + continue; + } } - if (HandleErrors(reply.NFS4Error(), serv, cookie, NULL, &sequence)) - continue; fFileSystem->OpenOwnerSequenceUnlock(sequence); if (result != B_OK) @@ -1146,6 +1164,7 @@ NFS4Inode::ReleaseLock(OpenFileCookie* cookie, LockInfo* lockInfo) ASSERT(cookie != NULL); ASSERT(lockInfo != NULL); + uint32 attempt = 0; do { MutexLocker ownerLocker(lockInfo->fOwner->fLock); @@ -1166,7 +1185,7 @@ NFS4Inode::ReleaseLock(OpenFileCookie* cookie, LockInfo* lockInfo) result = reply.LockU(lockInfo); ownerLocker.Unlock(); - if (HandleErrors(reply.NFS4Error(), serv, cookie)) + if (HandleErrors(attempt, reply.NFS4Error(), serv, cookie)) continue; if (result != B_OK) diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp index 69381930f9..c7f7827a2e 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp @@ -14,12 +14,22 @@ #include "Request.h" +static inline bigtime_t +RetryDelay(uint32 attempt, uint32 leaseTime = 0) +{ + attempt = min_c(attempt, sizeof(bigtime_t) * 8); + + bigtime_t delay = (1 << (attempt - 1)) * 100000; + if (leaseTime != 0) + delay = min_c(delay, sSecToBigTime(leaseTime)); + return delay; +} + + bool -NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, +NFS4Object::HandleErrors(uint32& attempt, uint32 nfs4Error, RPC::Server* server, OpenStateCookie* cookie, OpenState* state, uint32* sequence) { - uint32 leaseTime; - // No request send by the client should cause any of the following errors. ASSERT(nfs4Error != NFS4ERR_CLID_INUSE); ASSERT(nfs4Error != NFS4ERR_NOFILEHANDLE); @@ -28,17 +38,42 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, ASSERT(nfs4Error != NFS4ERR_LOCKS_HELD); ASSERT(nfs4Error != NFS4ERR_OP_ILLEGAL); + attempt++; + if (cookie != NULL) state = cookie->fOpenState; + uint32 leaseTime; + status_t result; switch (nfs4Error) { case NFS4_OK: return false; // retransmission of CLOSE caused seqid to fall back case NFS4ERR_BAD_SEQID: - ASSERT(sequence != NULL); - (*sequence)++; + if (attempt == 1) { + ASSERT(sequence != NULL); + (*sequence)++; + return true; + } + return false; + + // resource is locked, we need to wait + case NFS4ERR_DENIED: + if (sequence != NULL) + fFileSystem->OpenOwnerSequenceUnlock(*sequence); + + result = acquire_sem_etc(cookie->fSnoozeCancel, 1, + B_RELATIVE_TIMEOUT, RetryDelay(attempt)); + + if (sequence != NULL) + *sequence = fFileSystem->OpenOwnerSequenceLock(); + + if (result != B_TIMED_OUT) { + if (result == B_OK) + release_sem(cookie->fSnoozeCancel); + return false; + } return true; // server needs more time, we need to wait @@ -48,8 +83,9 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, fFileSystem->OpenOwnerSequenceUnlock(*sequence); if (cookie == NULL) { - snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE, + snooze_etc(RetryDelay(attempt), B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT); + if (sequence != NULL) *sequence = fFileSystem->OpenOwnerSequenceLock(); @@ -58,8 +94,8 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, } if ((cookie->fMode & O_NONBLOCK) == 0) { - status_t result = acquire_sem_etc(cookie->fSnoozeCancel, 1, - B_RELATIVE_TIMEOUT, sSecToBigTime(5)); + result = acquire_sem_etc(cookie->fSnoozeCancel, 1, + B_RELATIVE_TIMEOUT, RetryDelay(attempt)); if (sequence != NULL) *sequence = fFileSystem->OpenOwnerSequenceLock(); @@ -83,7 +119,7 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, fFileSystem->OpenOwnerSequenceUnlock(*sequence); if (cookie == NULL) { - snooze_etc(sSecToBigTime(leaseTime) / 3, B_SYSTEM_TIMEBASE, + snooze_etc(RetryDelay(attempt, leaseTime), B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT); if (sequence != NULL) *sequence = fFileSystem->OpenOwnerSequenceLock(); @@ -91,8 +127,8 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, } if ((cookie->fMode & O_NONBLOCK) == 0) { - status_t result = acquire_sem_etc(cookie->fSnoozeCancel, 1, - B_RELATIVE_TIMEOUT, sSecToBigTime(leaseTime) / 3); + result = acquire_sem_etc(cookie->fSnoozeCancel, 1, + B_RELATIVE_TIMEOUT, RetryDelay(attempt, leaseTime)); if (sequence != NULL) *sequence = fFileSystem->OpenOwnerSequenceLock(); @@ -125,7 +161,6 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, return false; // File Handle has expired, is invalid or the node has been deleted - case NFS4ERR_NOFILEHANDLE: case NFS4ERR_BADHANDLE: case NFS4ERR_FHEXPIRED: case NFS4ERR_STALE: @@ -136,7 +171,7 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, // filesystem has been moved case NFS4ERR_LEASE_MOVED: case NFS4ERR_MOVED: - fFileSystem->Migrate(serv); + fFileSystem->Migrate(server); return true; // lease has expired @@ -160,6 +195,7 @@ NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state, ASSERT(state != NULL); ASSERT(sequence != NULL); + uint32 attempt = 0; do { RPC::Server* serv = fFileSystem->Server(); Request request(serv, fFileSystem); @@ -175,12 +211,13 @@ NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state, ReplyInterpreter& reply = request.Reply(); - *sequence += IncrementSequence(reply.NFS4Error()); + result = reply.PutFH(); + if (result == B_OK) + *sequence += IncrementSequence(reply.NFS4Error()); - if (HandleErrors(reply.NFS4Error(), serv, NULL, state)) + if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, state)) continue; - reply.PutFH(); result = reply.OpenConfirm(&state->fStateSeq); if (result != B_OK) return result; diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h index d0ac9cb83a..2ec041e20a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h @@ -18,8 +18,8 @@ class OpenState; class NFS4Object { public: - bool HandleErrors(uint32 nfs4Error, RPC::Server* serv, - OpenStateCookie* cookie = NULL, + bool HandleErrors(uint32& attempt, uint32 nfs4Error, + RPC::Server* server, OpenStateCookie* cookie = NULL, OpenState* state = NULL, uint32* sequence = NULL); status_t ConfirmOpen(const FileHandle& fileHandle, diff --git a/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp b/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp index 21ac8d5b78..73df95155a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp @@ -114,6 +114,7 @@ OpenState::_ReleaseLockOwner(LockOwner* owner) { ASSERT(owner != NULL); + uint32 attempt = 0; do { RPC::Server* server = fFileSystem->Server(); Request request(server, fFileSystem); @@ -127,7 +128,7 @@ OpenState::_ReleaseLockOwner(LockOwner* owner) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), server)) + if (HandleErrors(attempt, reply.NFS4Error(), server)) continue; return reply.ReleaseLockOwner(); @@ -166,6 +167,7 @@ OpenState::_ReclaimOpen(uint64 newClientID) uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); OpenDelegation delegType = fDelegation != NULL ? fDelegation->Type() : OPEN_DELEGATE_NONE; + uint32 attempt = 0; do { RPC::Server* server = fFileSystem->Server(); Request request(server, fFileSystem); @@ -184,15 +186,16 @@ OpenState::_ReclaimOpen(uint64 newClientID) ReplyInterpreter& reply = request.Reply(); - sequence += IncrementSequence(reply.NFS4Error()); + result = reply.PutFH(); + if (result == B_OK) + sequence += IncrementSequence(reply.NFS4Error()); if (reply.NFS4Error() != NFS4ERR_STALE_CLIENTID - && HandleErrors(reply.NFS4Error(), server, NULL, NULL, &sequence)) { + && HandleErrors(attempt, reply.NFS4Error(), server, NULL, NULL, + &sequence)) { continue; } - reply.PutFH(); - result = reply.Open(fStateID, &fStateSeq, &confirm, &delegation); if (result != B_OK) { fFileSystem->OpenOwnerSequenceUnlock(sequence); @@ -233,6 +236,7 @@ OpenState::_ReclaimLocks(uint64 newClientID) linfo->fOwner->fClientId = newClientID; } + uint32 attempt = 0; uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); do { RPC::Server* server = fFileSystem->Server(); @@ -250,16 +254,17 @@ OpenState::_ReclaimLocks(uint64 newClientID) ReplyInterpreter& reply = request.Reply(); - sequence += IncrementSequence(reply.NFS4Error()); + result = reply.PutFH(); + if (result == B_OK) + sequence += IncrementSequence(reply.NFS4Error()); if (reply.NFS4Error() != NFS4ERR_STALE_CLIENTID && reply.NFS4Error() != NFS4ERR_STALE_STATEID - && HandleErrors(reply.NFS4Error(), server, NULL, NULL, + && HandleErrors(attempt, reply.NFS4Error(), server, NULL, NULL, &sequence)) { continue; } - reply.PutFH(); reply.Lock(linfo); fFileSystem->OpenOwnerSequenceUnlock(sequence); @@ -283,6 +288,7 @@ OpenState::Close() MutexLocker _(fLock); fOpened = false; + uint32 attempt = 0; uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); do { RPC::Server* serv = fFileSystem->Server(); @@ -300,7 +306,9 @@ OpenState::Close() ReplyInterpreter& reply = request.Reply(); - sequence += IncrementSequence(reply.NFS4Error()); + result = reply.PutFH(); + if (result == B_OK) + sequence += IncrementSequence(reply.NFS4Error()); // RFC 3530 8.10.1. Some servers does not do anything to help client // recognize retried CLOSE requests so we just assume that BAD_STATEID @@ -310,12 +318,12 @@ OpenState::Close() return B_OK; } - if (HandleErrors(reply.NFS4Error(), serv, NULL, this, &sequence)) + if (HandleErrors(attempt, reply.NFS4Error(), serv, NULL, this, + &sequence)) { continue; + } fFileSystem->OpenOwnerSequenceUnlock(sequence); - reply.PutFH(); - return reply.Close(); } while (true); } diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCServer.cpp b/src/add-ons/kernel/file_systems/nfs4/RPCServer.cpp index 7190fee8db..fc5cb132a1 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RPCServer.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RPCServer.cpp @@ -12,6 +12,7 @@ #include #include +#include #include "RPCCallbackServer.h" #include "RPCReply.h" @@ -83,7 +84,7 @@ Server::Server(Connection* connection, PeerAddress* address) fPrivateData(NULL), fCallback(NULL), fRepairCount(0), - fXID(rand() << 1) + fXID(get_random()) { ASSERT(connection != NULL); ASSERT(address != NULL); diff --git a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp index f900b846ae..e518f86681 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include "Cookie.h" #include "OpenState.h" #include "RPCCallback.h" @@ -659,8 +661,7 @@ RequestBuilder::SetClientID(RPC::Server* server) return B_NO_MEMORY; fRequest->Stream().AddUInt(OpSetClientID); - uint64 verifier = rand(); - verifier = verifier << 32 | rand(); + uint64 verifier = get_random(); fRequest->Stream().AddUHyper(verifier); status_t result = _GenerateClientId(fRequest->Stream(), server); diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp index e79f832823..ed9dee0615 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp @@ -58,6 +58,7 @@ RootInode::_UpdateInfo(bool force) if (fInfoCacheExpire > time(NULL)) return B_OK; + uint32 attempt = 0; do { RPC::Server* server = fFileSystem->Server(); Request request(server, fFileSystem); @@ -75,7 +76,7 @@ RootInode::_UpdateInfo(bool force) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), server)) + if (HandleErrors(attempt, reply.NFS4Error(), server)) continue; reply.PutFH(); @@ -146,6 +147,7 @@ RootInode::_UpdateInfo(bool force) bool RootInode::ProbeMigration() { + uint32 attempt = 0; do { RPC::Server* server = fFileSystem->Server(); Request request(server, fFileSystem); @@ -163,7 +165,7 @@ RootInode::ProbeMigration() if (reply.NFS4Error() == NFS4ERR_MOVED) return true; - if (HandleErrors(reply.NFS4Error(), server)) + if (HandleErrors(attempt, reply.NFS4Error(), server)) continue; return false; @@ -176,6 +178,7 @@ RootInode::GetLocations(AttrValue** attrv) { ASSERT(attrv != NULL); + uint32 attempt = 0; do { RPC::Server* server = fFileSystem->Server(); Request request(server, fFileSystem); @@ -191,7 +194,7 @@ RootInode::GetLocations(AttrValue** attrv) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), server)) + if (HandleErrors(attempt, reply.NFS4Error(), server)) continue; reply.PutFH(); diff --git a/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp b/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp index 2e20cfc22b..6e260bc4ba 100644 --- a/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp @@ -27,7 +27,7 @@ void VnodeToInode::Replace(Inode* newInode) { WriteLocker _(fLock); - if (fInode != NULL && !IsRoot()) + if (!IsRoot()) delete fInode; fInode = newInode; diff --git a/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.h b/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.h index b75528aaea..ee04a454c3 100644 --- a/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.h +++ b/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.h @@ -72,7 +72,7 @@ VnodeToInode::VnodeToInode(ino_t id, FileSystem* fileSystem) inline VnodeToInode::~VnodeToInode() { - Replace(NULL); + Clear(); if (fFileSystem != NULL && !IsRoot()) fFileSystem->InoIdMap()->RemoveEntry(fID); rw_lock_destroy(&fLock); @@ -96,10 +96,7 @@ VnodeToInode::Unlock() inline void VnodeToInode::Clear() { - WriteLocker _(fLock); - if (!IsRoot()) - delete fInode; - fInode = NULL; + Replace(NULL); } diff --git a/src/add-ons/kernel/file_systems/nfs4/WorkQueue.cpp b/src/add-ons/kernel/file_systems/nfs4/WorkQueue.cpp index da435bfb43..524b98346d 100644 --- a/src/add-ons/kernel/file_systems/nfs4/WorkQueue.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/WorkQueue.cpp @@ -12,6 +12,8 @@ #include +#define MAX_BUFFER_SIZE (1024 * 1024) + WorkQueue* gWorkQueue = NULL; @@ -152,43 +154,62 @@ WorkQueue::JobIO(IORequestArgs* args) uint64 offset = io_request_offset(args->fRequest); uint64 length = io_request_length(args->fRequest); - char* buffer = reinterpret_cast(malloc(length)); + size_t bufferLength = min_c(MAX_BUFFER_SIZE, length); + char* buffer = reinterpret_cast(malloc(bufferLength)); if (buffer == NULL) { notify_io_request(args->fRequest, B_NO_MEMORY); args->fInode->EndAIOOp(); return; } - bool eof = false; - uint64 size = 0; status_t result; if (io_request_is_write(args->fRequest)) { if (offset + length > args->fInode->MaxFileSize()) length = args->fInode->MaxFileSize() - offset; - result = read_from_io_request(args->fRequest, buffer, length); + uint64 position = 0; do { - size_t bytesWritten = length - size; - result = args->fInode->WriteDirect(NULL, offset + size, - buffer + size, &bytesWritten); - size += bytesWritten; - } while (size < length && result == B_OK); + size_t size = 0; + size_t thisBufferLength = min_c(bufferLength, length - position); + + result = read_from_io_request(args->fRequest, buffer, + thisBufferLength); + + while (size < thisBufferLength && result == B_OK) { + size_t bytesWritten = thisBufferLength - size; + result = args->fInode->WriteDirect(NULL, + offset + position + size, buffer + size, &bytesWritten); + size += bytesWritten; + } + + position += thisBufferLength; + } while (position < length && result == B_OK); } else { + bool eof = false; + uint64 position = 0; do { - size_t bytesRead = length - size; - result = args->fInode->ReadDirect(NULL, offset + size, buffer, - &bytesRead, &eof); - if (result != B_OK) - break; + size_t size = 0; + size_t thisBufferLength = min_c(bufferLength, length - position); - result = write_to_io_request(args->fRequest, buffer, bytesRead); - if (result != B_OK) - break; + do { + size_t bytesRead = thisBufferLength - size; + result = args->fInode->ReadDirect(NULL, + offset + position + size, buffer + size, &bytesRead, &eof); + if (result != B_OK) + break; - size += bytesRead; - } while (size < length && result == B_OK && !eof); - + result = write_to_io_request(args->fRequest, buffer + size, + bytesRead); + if (result != B_OK) + break; + + size += bytesRead; + } while (size < length && result == B_OK && !eof); + + position += thisBufferLength; + } while (position < length && result == B_OK && !eof); } + free(buffer); notify_io_request(args->fRequest, result); 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 2672ae0b2a..522a9eb477 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -691,7 +691,10 @@ nfs4_read_stat(fs_volume* volume, fs_vnode* vnode, struct stat* stat) if (inode == NULL) return B_ENTRY_NOT_FOUND; - return inode->Stat(stat); + status_t result = inode->Stat(stat); + if (inode->GetOpenState() != NULL) + stat->st_size = inode->MaxFileSize(); + return result; } diff --git a/src/add-ons/kernel/network/notifications/notifications.cpp b/src/add-ons/kernel/network/notifications/notifications.cpp index 7c2544cbc8..6d01979e65 100644 --- a/src/add-ons/kernel/network/notifications/notifications.cpp +++ b/src/add-ons/kernel/network/notifications/notifications.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2008-2013, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -21,16 +21,18 @@ class NetNotificationService : public DefaultUserNotificationService { public: - NetNotificationService(); - virtual ~NetNotificationService(); + NetNotificationService(); + virtual ~NetNotificationService(); - void Notify(const KMessage& event); + void Notify(const KMessage& event); protected: - virtual void FirstAdded(); - virtual void LastRemoved(); + virtual void LastReferenceReleased(); + virtual void FirstAdded(); + virtual void LastRemoved(); }; + static NetNotificationService sNotificationService; @@ -38,7 +40,8 @@ static NetNotificationService sNotificationService; NetNotificationService::NetNotificationService() - : DefaultUserNotificationService("network") + : + DefaultUserNotificationService("network") { } @@ -61,6 +64,13 @@ NetNotificationService::Notify(const KMessage& event) } +void +NetNotificationService::LastReferenceReleased() +{ + // don't delete us here +} + + void NetNotificationService::FirstAdded() { @@ -133,6 +143,9 @@ notifications_std_ops(int32 op, ...) unregister_generic_syscall(NET_NOTIFICATIONS_SYSCALLS, 1); + // we need to release the reference that was acquired + // on our behalf by the NotificationManager. +// sNotificationService.ReleaseReference(); sNotificationService.~NetNotificationService(); return B_OK; diff --git a/src/add-ons/kernel/network/protocols/udp/udp.cpp b/src/add-ons/kernel/network/protocols/udp/udp.cpp index 0e921ae895..9fd4327604 100644 --- a/src/add-ons/kernel/network/protocols/udp/udp.cpp +++ b/src/add-ons/kernel/network/protocols/udp/udp.cpp @@ -368,8 +368,11 @@ UdpDomainSupport::ConnectEndpoint(UdpEndpoint *endpoint, struct net_route *routeToDestination = gDatalinkModule->get_route(fDomain, address); if (routeToDestination) { + // stay bound to current local port, if any. + uint16 port = endpoint->LocalAddress().Port(); status = endpoint->LocalAddress().SetTo( routeToDestination->interface_address->local); + endpoint->LocalAddress().SetPort(port); gDatalinkModule->put_route(fDomain, routeToDestination); if (status < B_OK) return status; diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 053121c22a..139f5a9adb 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -139,12 +139,14 @@ Application Debugger : RetrieveMemoryBlockJob.cpp # model + AreaInfo.cpp Breakpoint.cpp DisassembledCode.cpp FileSourceCode.cpp Image.cpp ImageInfo.cpp ReturnValueInfo.cpp + SemaphoreInfo.cpp SourceCode.cpp StackFrame.cpp StackFrameValues.cpp @@ -152,6 +154,7 @@ Application Debugger : StackTrace.cpp Statement.cpp SymbolInfo.cpp + SystemInfo.cpp Team.cpp TeamMemory.cpp TeamMemoryBlock.cpp diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index e5aa62da9b..6abebe164c 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -1,13 +1,11 @@ /* - * Copyright 2012, Rene Gollent, rene@gollent.com. + * Copyright 2012-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #include "DebugReportGenerator.h" -#include - #include #include @@ -17,13 +15,17 @@ #include #include "Architecture.h" +#include "AreaInfo.h" #include "CpuState.h" +#include "DebuggerInterface.h" #include "Image.h" #include "MessageCodes.h" #include "Register.h" +#include "SemaphoreInfo.h" #include "StackFrame.h" #include "StackTrace.h" #include "StringUtils.h" +#include "SystemInfo.h" #include "Team.h" #include "Thread.h" #include "Type.h" @@ -37,16 +39,18 @@ DebugReportGenerator::DebugReportGenerator(::Team* team, - UserInterfaceListener* listener) + UserInterfaceListener* listener, DebuggerInterface* interface) : BLooper("DebugReportGenerator"), fTeam(team), fArchitecture(team->GetArchitecture()), + fDebuggerInterface(interface), fTeamDataSem(-1), fNodeManager(NULL), fListener(listener), fWaitingNode(NULL), fCurrentBlock(NULL), + fBlockRetrievalStatus(B_OK), fTraceWaitingThread(NULL) { fTeam->AddListener(this); @@ -88,9 +92,11 @@ DebugReportGenerator::Init() DebugReportGenerator* -DebugReportGenerator::Create(::Team* team, UserInterfaceListener* listener) +DebugReportGenerator::Create(::Team* team, UserInterfaceListener* listener, + DebuggerInterface* interface) { - DebugReportGenerator* self = new DebugReportGenerator(team, listener); + DebugReportGenerator* self = new DebugReportGenerator(team, listener, + interface); try { self->Init(); @@ -120,6 +126,14 @@ DebugReportGenerator::_GenerateReport(const entry_ref& outputPath) if (result != B_OK) return result; + result = _DumpAreas(output); + if (result != B_OK) + return result; + + result = _DumpSemaphores(output); + if (result != B_OK) + return result; + result = _DumpRunningThreads(output); if (result != B_OK) return result; @@ -168,13 +182,15 @@ DebugReportGenerator::ThreadStackTraceChanged(const ::Team::ThreadEvent& event) void DebugReportGenerator::MemoryBlockRetrieved(TeamMemoryBlock* block) { - if (fCurrentBlock != NULL) { - fCurrentBlock->ReleaseReference(); - fCurrentBlock = NULL; - } + _HandleMemoryBlockRetrieved(block, B_OK); +} - fCurrentBlock = block; - release_sem(fTeamDataSem); + +void +DebugReportGenerator::MemoryBlockRetrievalFailed(TeamMemoryBlock* block, + status_t result) +{ + _HandleMemoryBlockRetrieved(block, result); } @@ -198,11 +214,10 @@ DebugReportGenerator::_GenerateReportHeader(BString& _output) fTeam->Name(), fTeam->ID()); _output << data; - // TODO: this information should probably be requested via the debugger - // interface, since e.g. in the case of a remote team, the report should - // include data about the target, not the debugging host - system_info info; - if (get_system_info(&info) == B_OK) { + SystemInfo sysInfo; + + if (fDebuggerInterface->GetSystemInfo(sysInfo) == B_OK) { + const system_info &info = sysInfo.GetSystemInfo(); data.SetToFormat("CPU(s): %" B_PRId32 "x %s %s\n", info.cpu_count, get_cpu_vendor_string(info.cpu_type), get_cpu_model_string(&info)); @@ -216,11 +231,12 @@ DebugReportGenerator::_GenerateReportHeader(BString& _output) BPrivate::string_for_size((int64)info.used_pages * B_PAGE_SIZE, usedSize, sizeof(usedSize))); _output << data; + + const utsname& name = sysInfo.GetSystemName(); + data.SetToFormat("Haiku revision: %s (%s)\n", name.version, + name.machine); + _output << data; } - utsname name; - uname(&name); - data.SetToFormat("Haiku revision: %s (%s)\n", name.version, name.machine); - _output << data; return B_OK; } @@ -259,6 +275,69 @@ DebugReportGenerator::_DumpLoadedImages(BString& _output) } +status_t +DebugReportGenerator::_DumpAreas(BString& _output) +{ + BObjectList areas(20, true); + status_t result = fDebuggerInterface->GetAreaInfos(areas); + if (result != B_OK) + return result; + + _output << "\nAreas:\n"; + BString data; + AreaInfo* info; + BString protectionBuffer; + char lockingBuffer[32]; + for (int32 i = 0; (info = areas.ItemAt(i)) != NULL; i++) { + try { + data.SetToFormat("\t%s (%" B_PRId32 ") " + "Base: %#08" B_PRIx64 ", Size: %" B_PRId64 + ", RAM Size: %" B_PRId64 ",Locking: %s, Protection: %s\n", + info->Name().String(), info->AreaID(), info->BaseAddress(), + info->Size(), info->RamSize(), + UiUtils::AreaLockingFlagsToString(info->Lock(), lockingBuffer, + sizeof(lockingBuffer)), + UiUtils::AreaProtectionFlagsToString(info->Protection(), + protectionBuffer).String()); + + _output << data; + } catch (...) { + return B_NO_MEMORY; + } + } + + return B_OK; +} + + +status_t +DebugReportGenerator::_DumpSemaphores(BString& _output) +{ + BObjectList semaphores(20, true); + status_t result = fDebuggerInterface->GetSemaphoreInfos(semaphores); + if (result != B_OK) + return result; + + _output << "\nSemaphores:\n"; + BString data; + SemaphoreInfo* info; + for (int32 i = 0; (info = semaphores.ItemAt(i)) != NULL; i++) { + try { + data.SetToFormat("\t%s (%" B_PRId32 ") " + "Count: %" B_PRId32 ", Latest Holding Thread: %" B_PRId32 "\n", + info->Name().String(), info->SemID(), info->Count(), + info->LatestHolder()); + + _output << data; + } catch (...) { + return B_NO_MEMORY; + } + } + + return B_OK; +} + + status_t DebugReportGenerator::_DumpRunningThreads(BString& _output) { @@ -408,8 +487,16 @@ DebugReportGenerator::_DumpStackFrameMemory(BString& _output, } _output << "\t\t\tFrame memory:\n"; - UiUtils::DumpMemory(_output, 3, fCurrentBlock, startAddress, 1, 16, - endAddress - startAddress); + if (fBlockRetrievalStatus == B_OK) { + UiUtils::DumpMemory(_output, 3, fCurrentBlock, startAddress, 1, 16, + endAddress - startAddress); + } else { + BString data; + data.SetToFormat("\t\t\tUnavailable (%s)\n", strerror( + fBlockRetrievalStatus)); + _output += data; + } + } @@ -451,3 +538,19 @@ DebugReportGenerator::_ResolveValueIfNeeded(ValueNode* node, StackFrame* frame, return result; } + + +void +DebugReportGenerator::_HandleMemoryBlockRetrieved(TeamMemoryBlock* block, + status_t result) +{ + if (fCurrentBlock != NULL) { + fCurrentBlock->ReleaseReference(); + fCurrentBlock = NULL; + } + + fBlockRetrievalStatus = result; + + fCurrentBlock = block; + release_sem(fTeamDataSem); +} diff --git a/src/apps/debugger/controllers/DebugReportGenerator.h b/src/apps/debugger/controllers/DebugReportGenerator.h index 5ff78b484d..f19fa1bf97 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.h +++ b/src/apps/debugger/controllers/DebugReportGenerator.h @@ -1,5 +1,5 @@ /* - * Copyright 2012, Rene Gollent, rene@gollent.com. + * Copyright 2012-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DEBUG_REPORT_GENERATOR_H @@ -16,6 +16,7 @@ class entry_ref; class Architecture; class BString; +class DebuggerInterface; class StackFrame; class Team; class Thread; @@ -30,13 +31,15 @@ class DebugReportGenerator : public BLooper, private Team::Listener, private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener { public: DebugReportGenerator(::Team* team, - UserInterfaceListener* listener); + UserInterfaceListener* listener, + DebuggerInterface* interface); ~DebugReportGenerator(); status_t Init(); static DebugReportGenerator* Create(::Team* team, - UserInterfaceListener* listener); + UserInterfaceListener* listener, + DebuggerInterface* interface); virtual void MessageReceived(BMessage* message); @@ -47,6 +50,8 @@ private: // TeamMemoryBlock::Listener virtual void MemoryBlockRetrieved(TeamMemoryBlock* block); + virtual void MemoryBlockRetrievalFailed( + TeamMemoryBlock* block, status_t result); // ValueNodeContainer::Listener virtual void ValueNodeValueChanged(ValueNode* node); @@ -56,6 +61,8 @@ private: status_t _GenerateReport(const entry_ref& outputPath); status_t _GenerateReportHeader(BString& _output); status_t _DumpLoadedImages(BString& _output); + status_t _DumpAreas(BString& _output); + status_t _DumpSemaphores(BString& _output); status_t _DumpRunningThreads(BString& _output); status_t _DumpDebuggedThreadInfo(BString& _output, ::Thread* thread); @@ -67,14 +74,19 @@ private: status_t _ResolveValueIfNeeded(ValueNode* node, StackFrame* frame, int32 maxDepth); + void _HandleMemoryBlockRetrieved( + TeamMemoryBlock* block, status_t result); + private: ::Team* fTeam; Architecture* fArchitecture; + DebuggerInterface* fDebuggerInterface; sem_id fTeamDataSem; ValueNodeManager* fNodeManager; UserInterfaceListener* fListener; ValueNode* fWaitingNode; TeamMemoryBlock* fCurrentBlock; + status_t fBlockRetrievalStatus; ::Thread* fTraceWaitingThread; }; diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index 634eba0d0d..433e8ef61c 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -416,7 +416,8 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) return error; // create the debug report generator - fReportGenerator = new(std::nothrow) DebugReportGenerator(fTeam, this); + fReportGenerator = new(std::nothrow) DebugReportGenerator(fTeam, this, + fDebuggerInterface); if (fReportGenerator == NULL) return B_NO_MEMORY; diff --git a/src/apps/debugger/debug_info/DwarfTypes.cpp b/src/apps/debugger/debug_info/DwarfTypes.cpp index 20c52de259..b7fabfdfb8 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.cpp +++ b/src/apps/debugger/debug_info/DwarfTypes.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copryight 2012, Rene Gollent, rene@gollent.com. + * Copryight 2012-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -245,6 +245,50 @@ DwarfType::CreateDerivedAddressType(address_type_kind addressType, if (resultType == NULL) return B_NO_MEMORY; + resultType->SetByteSize(fTypeContext->GetArchitecture()->AddressSize()); + + _resultType = resultType; + return B_OK; +} + + +status_t +DwarfType::CreateDerivedArrayType(int64 lowerBound, int64 elementCount, + bool extendExisting, ArrayType*& _resultType) +{ + DwarfArrayType* resultType = NULL; + BReference baseTypeReference; + if (extendExisting) + resultType = dynamic_cast(this); + + if (resultType == NULL) { + resultType = new(std::nothrow) + DwarfArrayType(fTypeContext, fName, NULL, this); + baseTypeReference.SetTo(resultType, true); + } + + if (resultType == NULL) + return B_NO_MEMORY; + + DwarfSubrangeType* subrangeType = new(std::nothrow) DwarfSubrangeType( + fTypeContext, fName, NULL, resultType, BVariant(lowerBound), + BVariant(lowerBound + elementCount - 1)); + if (subrangeType == NULL) + return B_NO_MEMORY; + + BReference subrangeReference(subrangeType, true); + + DwarfArrayDimension* dimension = new(std::nothrow) DwarfArrayDimension( + subrangeType); + if (dimension == NULL) + return B_NO_MEMORY; + BReference dimensionReference(dimension, true); + + if (!resultType->AddDimension(dimension)) + return B_NO_MEMORY; + + baseTypeReference.Detach(); + _resultType = resultType; return B_OK; } @@ -949,8 +993,9 @@ DwarfArrayType::ResolveElementLocation(const ArrayIndexPath& indexPath, // If the array entry has a bit stride, get it. Otherwise fall back to the // element type size. int64 bitStride; - if (DIEArrayType* bitStrideOwnerEntry = DwarfUtils::GetDIEByPredicate( - fEntry, HasBitStridePredicate())) { + DIEArrayType* bitStrideOwnerEntry = NULL; + if (fEntry != NULL && (bitStrideOwnerEntry = DwarfUtils::GetDIEByPredicate( + fEntry, HasBitStridePredicate()))) { BVariant value; status_t error = typeContext->File()->EvaluateDynamicValue( typeContext->GetCompilationUnit(), typeContext->AddressSize(), diff --git a/src/apps/debugger/debug_info/DwarfTypes.h b/src/apps/debugger/debug_info/DwarfTypes.h index 628bae5416..f95b1a640c 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.h +++ b/src/apps/debugger/debug_info/DwarfTypes.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copryight 2012, Rene Gollent, rene@gollent.com. + * Copyright 2012-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_TYPES_H @@ -114,6 +114,12 @@ public: address_type_kind kind, AddressType*& _resultType); + virtual status_t CreateDerivedArrayType( + int64 lowerBound, + int64 elementCount, + bool extendExisting, + ArrayType*& _resultType); + virtual status_t ResolveObjectDataLocation( const ValueLocation& objectLocation, ValueLocation*& _location); diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp index 585327d633..641d9dc8d6 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.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. */ @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -23,10 +22,13 @@ #include "ArchitectureX86.h" #include "ArchitectureX8664.h" +#include "AreaInfo.h" #include "CpuState.h" #include "DebugEvent.h" #include "ImageInfo.h" +#include "SemaphoreInfo.h" #include "SymbolInfo.h" +#include "SystemInfo.h" #include "ThreadInfo.h" @@ -462,6 +464,24 @@ DebuggerInterface::UninstallWatchpoint(target_addr_t address) } +status_t +DebuggerInterface::GetSystemInfo(SystemInfo& info) +{ + system_info sysInfo; + status_t result = get_system_info(&sysInfo); + if (result != B_OK) + return result; + + utsname name; + result = uname(&name); + if (result != B_OK) + return result; + + info.SetTo(fTeamID, sysInfo, name); + return B_OK; +} + + status_t DebuggerInterface::GetThreadInfos(BObjectList& infos) { @@ -496,21 +516,42 @@ DebuggerInterface::GetImageInfos(BObjectList& infos) } } - // Also add the "commpage" image, which belongs to the kernel, but is used - // by userland teams. - cookie = 0; - while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &imageInfo) == B_OK) { - if ((addr_t)imageInfo.text >= USER_COMMPAGE_ADDR - && (addr_t)imageInfo.text < USER_COMMPAGE_ADDR + COMMPAGE_SIZE) { - ImageInfo* info = new(std::nothrow) ImageInfo(B_SYSTEM_TEAM, - imageInfo.id, imageInfo.name, imageInfo.type, - (addr_t)imageInfo.text, imageInfo.text_size, - (addr_t)imageInfo.data, imageInfo.data_size); - if (info == NULL || !infos.AddItem(info)) { - delete info; - return B_NO_MEMORY; - } - break; + return B_OK; +} + + +status_t +DebuggerInterface::GetAreaInfos(BObjectList& infos) +{ + // get the team's areas + area_info areaInfo; + ssize_t cookie = 0; + while (get_next_area_info(fTeamID, &cookie, &areaInfo) == B_OK) { + AreaInfo* info = new(std::nothrow) AreaInfo(fTeamID, areaInfo.area, + areaInfo.name, (addr_t)areaInfo.address, areaInfo.size, + areaInfo.ram_size, areaInfo.lock, areaInfo.protection); + if (info == NULL || !infos.AddItem(info)) { + delete info; + return B_NO_MEMORY; + } + } + + return B_OK; +} + + +status_t +DebuggerInterface::GetSemaphoreInfos(BObjectList& infos) +{ + // get the team's semaphores + sem_info semInfo; + int32 cookie = 0; + while (get_next_sem_info(fTeamID, &cookie, &semInfo) == B_OK) { + SemaphoreInfo* info = new(std::nothrow) SemaphoreInfo(fTeamID, + semInfo.sem, semInfo.name, semInfo.count, semInfo.latest_holder); + if (info == NULL || !infos.AddItem(info)) { + delete info; + return B_NO_MEMORY; } } diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.h b/src/apps/debugger/debugger_interface/DebuggerInterface.h index bdf9b2c9c9..f726074da5 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.h +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.h @@ -1,6 +1,6 @@ /* * Copyright 2009, 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. */ #ifndef DEBUGGER_INTERFACE_H @@ -17,8 +17,11 @@ class Architecture; class CpuState; class DebugEvent; +class AreaInfo; class ImageInfo; +class SemaphoreInfo; class SymbolInfo; +class SystemInfo; class ThreadInfo; namespace BPrivate { @@ -52,8 +55,12 @@ public: uint32 type, int32 length); virtual status_t UninstallWatchpoint(target_addr_t address); + virtual status_t GetSystemInfo(SystemInfo& info); virtual status_t GetThreadInfos(BObjectList& infos); virtual status_t GetImageInfos(BObjectList& infos); + virtual status_t GetAreaInfos(BObjectList& infos); + virtual status_t GetSemaphoreInfos( + BObjectList& infos); virtual status_t GetSymbolInfos(team_id team, image_id image, BObjectList& infos); virtual status_t GetSymbolInfo(team_id team, image_id image, diff --git a/src/apps/debugger/jobs/RetrieveMemoryBlockJob.cpp b/src/apps/debugger/jobs/RetrieveMemoryBlockJob.cpp index 888bfa4ae8..1a41b025ef 100644 --- a/src/apps/debugger/jobs/RetrieveMemoryBlockJob.cpp +++ b/src/apps/debugger/jobs/RetrieveMemoryBlockJob.cpp @@ -46,15 +46,19 @@ RetrieveMemoryBlockJob::Do() { ssize_t result = fTeamMemory->ReadMemory(fMemoryBlock->BaseAddress(), fMemoryBlock->Data(), fMemoryBlock->Size()); - if (result < 0) + if (result < 0) { + fMemoryBlock->NotifyDataRetrieved(result); return result; + } uint32 protection = 0; uint32 locking = 0; status_t error = get_memory_properties(fTeam->ID(), (const void *)fMemoryBlock->BaseAddress(), &protection, &locking); - if (error != B_OK) + if (error != B_OK) { + fMemoryBlock->NotifyDataRetrieved(error); return error; + } fMemoryBlock->SetWritable((protection & B_WRITE_AREA) != 0); fMemoryBlock->MarkValid(); diff --git a/src/apps/debugger/model/AreaInfo.cpp b/src/apps/debugger/model/AreaInfo.cpp new file mode 100644 index 0000000000..ee1a856324 --- /dev/null +++ b/src/apps/debugger/model/AreaInfo.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "AreaInfo.h" + + +AreaInfo::AreaInfo() + : + fTeam(-1), + fArea(-1), + fName(), + fAddress(0), + fSize(0), + fRamSize(0), + fLock(0), + fProtection(0) +{ +} + + +AreaInfo::AreaInfo(const AreaInfo &other) + : + fTeam(other.fTeam), + fArea(other.fArea), + fName(other.fName), + fAddress(other.fAddress), + fSize(other.fSize), + fRamSize(other.fRamSize), + fLock(other.fLock), + fProtection(other.fProtection) +{ +} + + +AreaInfo::AreaInfo(team_id team, area_id area, const BString& name, + target_addr_t address, target_size_t size, target_size_t ramSize, + uint32 lock, uint32 protection) + : + fTeam(team), + fArea(area), + fName(name), + fAddress(address), + fSize(size), + fRamSize(ramSize), + fLock(lock), + fProtection(protection) +{ +} + + +void +AreaInfo::SetTo(team_id team, area_id area, const BString& name, + target_addr_t address, target_size_t size, target_size_t ramSize, + uint32 lock, uint32 protection) +{ + fTeam = team; + fArea = area; + fName = name; + fAddress = address; + fSize = size; + fRamSize = ramSize; + fLock = lock; + fProtection = protection; +} diff --git a/src/apps/debugger/model/AreaInfo.h b/src/apps/debugger/model/AreaInfo.h new file mode 100644 index 0000000000..660673e917 --- /dev/null +++ b/src/apps/debugger/model/AreaInfo.h @@ -0,0 +1,51 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef AREA_INFO_H +#define AREA_INFO_H + +#include +#include + +#include "Types.h" + + +class AreaInfo { +public: + AreaInfo(); + AreaInfo(const AreaInfo& other); + AreaInfo(team_id team, area_id area, + const BString& name, target_addr_t address, + target_size_t size, target_size_t ram_size, + uint32 lock, uint32 protection); + + void SetTo(team_id team, area_id area, + const BString& name, target_addr_t address, + target_size_t size, target_size_t ram_size, + uint32 lock, uint32 protection); + + team_id TeamID() const { return fTeam; } + area_id AreaID() const { return fArea; } + const BString& Name() const { return fName; } + + target_addr_t BaseAddress() const { return fAddress; } + target_size_t Size() const { return fSize; } + target_size_t RamSize() const { return fRamSize; } + uint32 Lock() const { return fLock; } + uint32 Protection() const { return fProtection; } + + +private: + team_id fTeam; + area_id fArea; + BString fName; + target_addr_t fAddress; + target_size_t fSize; + target_size_t fRamSize; + uint32 fLock; + uint32 fProtection; +}; + + +#endif // AREA_INFO_H diff --git a/src/apps/debugger/model/SemaphoreInfo.cpp b/src/apps/debugger/model/SemaphoreInfo.cpp new file mode 100644 index 0000000000..8d7eddd951 --- /dev/null +++ b/src/apps/debugger/model/SemaphoreInfo.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "SemaphoreInfo.h" + + +SemaphoreInfo::SemaphoreInfo() + : + fTeam(-1), + fSemaphore(-1), + fName(), + fCount(0), + fLatestHolder(-1) +{ +} + + +SemaphoreInfo::SemaphoreInfo(const SemaphoreInfo &other) + : + fTeam(other.fTeam), + fSemaphore(other.fSemaphore), + fName(other.fName), + fCount(other.fCount), + fLatestHolder(other.fLatestHolder) +{ +} + + +SemaphoreInfo::SemaphoreInfo(team_id team, sem_id semaphore, + const BString& name, int32 count, thread_id latestHolder) + : + fTeam(team), + fSemaphore(semaphore), + fName(name), + fCount(count), + fLatestHolder(latestHolder) +{ +} + + +void +SemaphoreInfo::SetTo(team_id team, sem_id semaphore, const BString& name, + int32 count, thread_id latestHolder) +{ + fTeam = team; + fSemaphore = semaphore; + fName = name; + fCount = count; + fLatestHolder = latestHolder; +} diff --git a/src/apps/debugger/model/SemaphoreInfo.h b/src/apps/debugger/model/SemaphoreInfo.h new file mode 100644 index 0000000000..579bdcbb3a --- /dev/null +++ b/src/apps/debugger/model/SemaphoreInfo.h @@ -0,0 +1,42 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef SEMAPHORE_INFO_H +#define SEMAPHORE_INFO_H + +#include +#include + +#include "Types.h" + + +class SemaphoreInfo { +public: + SemaphoreInfo(); + SemaphoreInfo(const SemaphoreInfo& other); + SemaphoreInfo(team_id team, sem_id semaphore, + const BString& name, int32 count, + thread_id latestHolder); + + void SetTo(team_id team, sem_id semaphore, + const BString& name, int32 count, + thread_id latestHolder); + + team_id TeamID() const { return fTeam; } + area_id SemID() const { return fSemaphore; } + const BString& Name() const { return fName; } + + int32 Count() const { return fCount; } + thread_id LatestHolder() const + { return fLatestHolder; } +private: + team_id fTeam; + sem_id fSemaphore; + BString fName; + int32 fCount; + thread_id fLatestHolder; +}; + + +#endif // AREA_INFO_H diff --git a/src/apps/debugger/model/SystemInfo.cpp b/src/apps/debugger/model/SystemInfo.cpp new file mode 100644 index 0000000000..3a0b0c70fa --- /dev/null +++ b/src/apps/debugger/model/SystemInfo.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "SystemInfo.h" + + +SystemInfo::SystemInfo() + : + fTeam(-1) +{ + memset(&fSystemInfo, 0, sizeof(system_info)); + memset(&fSystemName, 0, sizeof(utsname)); +} + + +SystemInfo::SystemInfo(const SystemInfo &other) +{ + SetTo(other.fTeam, other.fSystemInfo, other.fSystemName); +} + + +SystemInfo::SystemInfo(team_id team, const system_info& info, + const utsname& name) +{ + SetTo(team, info, name); +} + + +void +SystemInfo::SetTo(team_id team, const system_info& info, const utsname& name) +{ + fTeam = team; + memcpy(&fSystemInfo, &info, sizeof(system_info)); + memcpy(&fSystemName, &name, sizeof(utsname)); +} diff --git a/src/apps/debugger/model/SystemInfo.h b/src/apps/debugger/model/SystemInfo.h new file mode 100644 index 0000000000..a6c6eb1b60 --- /dev/null +++ b/src/apps/debugger/model/SystemInfo.h @@ -0,0 +1,40 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef SYSTEM_INFO_H +#define SYSTEM_INFO_H + +#include + +#include +#include + +#include "Types.h" + + +class SystemInfo { +public: + SystemInfo(); + SystemInfo(const SystemInfo& other); + SystemInfo(team_id team, + const system_info& info, + const utsname& name); + + void SetTo(team_id team, const system_info& info, + const utsname& name); + + team_id TeamID() const { return fTeam; } + + const system_info& GetSystemInfo() const { return fSystemInfo; } + + const utsname& GetSystemName() const { return fSystemName; } + +private: + team_id fTeam; + system_info fSystemInfo; + utsname fSystemName; +}; + + +#endif // SYSTEM_INFO_H diff --git a/src/apps/debugger/model/TeamMemoryBlock.cpp b/src/apps/debugger/model/TeamMemoryBlock.cpp index 2bae7c303d..7b906531dc 100644 --- a/src/apps/debugger/model/TeamMemoryBlock.cpp +++ b/src/apps/debugger/model/TeamMemoryBlock.cpp @@ -93,11 +93,14 @@ TeamMemoryBlock::SetWritable(bool writable) void -TeamMemoryBlock::NotifyDataRetrieved() +TeamMemoryBlock::NotifyDataRetrieved(status_t result) { for (ListenerList::Iterator it = fListeners.GetIterator(); Listener* listener = it.Next();) { - listener->MemoryBlockRetrieved(this); + if (result == B_OK) + listener->MemoryBlockRetrieved(this); + else + listener->MemoryBlockRetrievalFailed(this, result); } } @@ -123,3 +126,10 @@ void TeamMemoryBlock::Listener::MemoryBlockRetrieved(TeamMemoryBlock* block) { } + + +void +TeamMemoryBlock::Listener::MemoryBlockRetrievalFailed(TeamMemoryBlock* block, + status_t result) +{ +} diff --git a/src/apps/debugger/model/TeamMemoryBlock.h b/src/apps/debugger/model/TeamMemoryBlock.h index c02bd67069..da347b2908 100644 --- a/src/apps/debugger/model/TeamMemoryBlock.h +++ b/src/apps/debugger/model/TeamMemoryBlock.h @@ -44,7 +44,7 @@ public: bool IsWritable() const { return fWritable; } void SetWritable(bool writable); - void NotifyDataRetrieved(); + void NotifyDataRetrieved(status_t result = B_OK); protected: virtual void LastReferenceReleased(); @@ -69,6 +69,9 @@ public: virtual ~Listener(); virtual void MemoryBlockRetrieved(TeamMemoryBlock* block); + + virtual void MemoryBlockRetrievalFailed(TeamMemoryBlock* block, + status_t result); }; diff --git a/src/apps/debugger/model/Type.cpp b/src/apps/debugger/model/Type.cpp index cf81243118..318abf2f26 100644 --- a/src/apps/debugger/model/Type.cpp +++ b/src/apps/debugger/model/Type.cpp @@ -104,6 +104,15 @@ Type::CreateDerivedAddressType(address_type_kind kind, } +status_t +Type::CreateDerivedArrayType(int64 lowerBound, int64 elementCount, + bool extendExisting, ArrayType*& _resultType) +{ + _resultType = NULL; + return B_ERROR; +} + + // #pragma mark - PrimitiveType diff --git a/src/apps/debugger/model/Type.h b/src/apps/debugger/model/Type.h index 5c097da5e8..8ebf55adbe 100644 --- a/src/apps/debugger/model/Type.h +++ b/src/apps/debugger/model/Type.h @@ -60,6 +60,7 @@ enum { class AddressType; class ArrayIndexPath; +class ArrayType; class BString; class Type; class ValueLocation; @@ -135,11 +136,22 @@ public: // if requested) - // TODO: also need the ability to derive array types virtual status_t CreateDerivedAddressType( address_type_kind kind, AddressType*& _resultType); + virtual status_t CreateDerivedArrayType( + int64 lowerBound, + int64 elementCount, + bool extendExisting, + // if the current object is already + // an array type, attach an extra + // dimension to it rather than + // creating a new encapsulating + // type object + ArrayType*& _resultType); + + virtual status_t ResolveObjectDataLocation( const ValueLocation& objectLocation, ValueLocation*& _location) = 0; diff --git a/src/apps/debugger/settings/generic/Settings.cpp b/src/apps/debugger/settings/generic/Settings.cpp index 686b729d40..dfc176d3a7 100644 --- a/src/apps/debugger/settings/generic/Settings.cpp +++ b/src/apps/debugger/settings/generic/Settings.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2013, Rene Gollent, rene@gollent.com. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -81,6 +82,24 @@ Settings::SetValue(Setting* setting, const BVariant& value) } +bool +Settings::RestoreValues(const BMessage& message) +{ + AutoLocker locker(fLock); + + for (int32 i = 0; i < fDescription->CountSettings(); i++) { + Setting* setting = fDescription->SettingAt(i); + BVariant value; + if (value.SetFromMessage(message, setting->ID()) == B_OK) { + if (!SetValue(setting, value)) + return false; + } + } + + return true; +} + + SettingsOption* Settings::OptionValue(OptionsSetting* setting) const { diff --git a/src/apps/debugger/settings/generic/Settings.h b/src/apps/debugger/settings/generic/Settings.h index 5862fa3a02..b921702c1e 100644 --- a/src/apps/debugger/settings/generic/Settings.h +++ b/src/apps/debugger/settings/generic/Settings.h @@ -1,4 +1,5 @@ /* + * Copyright 2013, Rene Gollent, rene@gollent.com. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -40,6 +41,8 @@ public: bool SetValue(Setting* setting, const BVariant& value); + bool RestoreValues(const BMessage& message); + bool BoolValue(BoolSetting* setting) const { return Value(setting).ToBool(); } SettingsOption* OptionValue(OptionsSetting* setting) const; diff --git a/src/apps/debugger/source_language/CLanguage.cpp b/src/apps/debugger/source_language/CLanguage.cpp index 0114bf4ae3..27f063ef89 100644 --- a/src/apps/debugger/source_language/CLanguage.cpp +++ b/src/apps/debugger/source_language/CLanguage.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2013, Rene Gollent, rene@gollent.com. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -22,3 +23,13 @@ CLanguage::Name() const { return "C"; } + + +bool +CLanguage::IsModifierValid(char modifier) const +{ + if (modifier == '*') + return true; + + return false; +} diff --git a/src/apps/debugger/source_language/CLanguage.h b/src/apps/debugger/source_language/CLanguage.h index f0b27ed828..959cda91fe 100644 --- a/src/apps/debugger/source_language/CLanguage.h +++ b/src/apps/debugger/source_language/CLanguage.h @@ -15,6 +15,9 @@ public: virtual ~CLanguage(); virtual const char* Name() const; + +protected: + virtual bool IsModifierValid(char modifier) const; }; diff --git a/src/apps/debugger/source_language/CLanguageFamily.cpp b/src/apps/debugger/source_language/CLanguageFamily.cpp index 0eb45b2cb3..592cf53009 100644 --- a/src/apps/debugger/source_language/CLanguageFamily.cpp +++ b/src/apps/debugger/source_language/CLanguageFamily.cpp @@ -1,10 +1,18 @@ /* + * Copyright 2013, Rene Gollent, rene@gollent.com. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #include "CLanguageFamily.h" +#include + +#include "TeamTypeInformation.h" +#include "Type.h" +#include "TypeLookupConstraints.h" + + CLanguageFamily::CLanguageFamily() { @@ -22,3 +30,131 @@ CLanguageFamily::GetSyntaxHighlighter() const // TODO:... return NULL; } + + +status_t +CLanguageFamily::ParseTypeExpression(const BString& expression, + TeamTypeInformation* info, Type*& _resultType) const +{ + status_t result = B_OK; + Type* baseType = NULL; + + BString parsedName = expression; + BString baseTypeName; + BString arraySpecifier; + parsedName.RemoveAll(" "); + + int32 modifierIndex = -1; + modifierIndex = parsedName.FindFirst('*'); + if (modifierIndex == -1) + modifierIndex = parsedName.FindFirst('&'); + if (modifierIndex == -1) + modifierIndex = parsedName.FindFirst('['); + + if (modifierIndex >= 0) + parsedName.MoveInto(baseTypeName, 0, modifierIndex); + else + baseTypeName = parsedName; + + modifierIndex = parsedName.FindFirst('['); + if (modifierIndex >= 0) { + parsedName.MoveInto(arraySpecifier, modifierIndex, + parsedName.Length() - modifierIndex); + } + + result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(), + baseType); + if (result != B_OK) + return result; + + BReference typeRef; + typeRef.SetTo(baseType, true); + + if (!parsedName.IsEmpty()) { + AddressType* derivedType = NULL; + // walk the list of modifiers trying to add each. + for (int32 i = 0; i < parsedName.Length(); i++) { + if (!IsModifierValid(parsedName[i])) + return B_BAD_VALUE; + + address_type_kind typeKind; + switch (parsedName[i]) { + case '*': + { + typeKind = DERIVED_TYPE_POINTER; + break; + } + case '&': + { + typeKind = DERIVED_TYPE_REFERENCE; + break; + } + default: + { + return B_BAD_VALUE; + } + + } + + if (derivedType == NULL) { + result = baseType->CreateDerivedAddressType(typeKind, + derivedType); + } else { + result = derivedType->CreateDerivedAddressType(typeKind, + derivedType); + } + + if (result != B_OK) + return result; + typeRef.SetTo(derivedType, true); + } + + _resultType = derivedType; + } else + _resultType = baseType; + + + if (!arraySpecifier.IsEmpty()) { + ArrayType* arrayType = NULL; + + int32 startIndex = 1; + do { + int32 size = strtoul(arraySpecifier.String() + startIndex, + NULL, 10); + if (size < 0) + return B_ERROR; + + if (arrayType == NULL) { + result = _resultType->CreateDerivedArrayType(0, size, true, + arrayType); + } else { + result = arrayType->CreateDerivedArrayType(0, size, true, + arrayType); + } + + if (result != B_OK) + return result; + + typeRef.SetTo(arrayType, true); + + startIndex = arraySpecifier.FindFirst('[', startIndex + 1); + + } while (startIndex >= 0); + + // since a C/C++ array is essentially pointer math, + // the resulting array has to be wrapped in a pointer to + // ensure the element addresses wind up being against the + // correct address. + AddressType* addressType = NULL; + result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER, + addressType); + if (result != B_OK) + return result; + + _resultType = addressType; + } + + typeRef.Detach(); + + return result; +} diff --git a/src/apps/debugger/source_language/CLanguageFamily.h b/src/apps/debugger/source_language/CLanguageFamily.h index 6703a380ca..250639bec7 100644 --- a/src/apps/debugger/source_language/CLanguageFamily.h +++ b/src/apps/debugger/source_language/CLanguageFamily.h @@ -15,6 +15,13 @@ public: virtual ~CLanguageFamily(); virtual SyntaxHighlighter* GetSyntaxHighlighter() const; + + virtual status_t ParseTypeExpression(const BString& expression, + TeamTypeInformation* lookup, + Type*& _resultType) const; + +protected: + virtual bool IsModifierValid(char modifier) const = 0; }; diff --git a/src/apps/debugger/source_language/CppLanguage.cpp b/src/apps/debugger/source_language/CppLanguage.cpp index 2aa19301de..201107f989 100644 --- a/src/apps/debugger/source_language/CppLanguage.cpp +++ b/src/apps/debugger/source_language/CppLanguage.cpp @@ -1,16 +1,12 @@ /* * 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. */ #include "CppLanguage.h" -#include "TeamTypeInformation.h" -#include "Type.h" -#include "TypeLookupConstraints.h" - CppLanguage::CppLanguage() { @@ -29,79 +25,11 @@ CppLanguage::Name() const } -status_t -CppLanguage::ParseTypeExpression(const BString &expression, - TeamTypeInformation* info, - Type*& _resultType) const +bool +CppLanguage::IsModifierValid(char modifier) const { - status_t result = B_OK; - Type* baseType = NULL; + if (modifier == '*' || modifier == '&') + return true; - BString parsedName = expression; - BString baseTypeName; - parsedName.RemoveAll(" "); - - int32 modifierIndex = -1; - for (int32 i = parsedName.Length() - 1; i >= 0; i--) { - if (parsedName[i] == '*' || parsedName[i] == '&') - modifierIndex = i; - } - - if (modifierIndex >= 0) { - parsedName.CopyInto(baseTypeName, 0, modifierIndex); - parsedName.Remove(0, modifierIndex); - } else - baseTypeName = parsedName; - - result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(), - baseType); - if (result != B_OK) - return result; - - BReference typeRef; - typeRef.SetTo(baseType, true); - - if (!parsedName.IsEmpty()) { - AddressType* derivedType = NULL; - // walk the list of modifiers trying to add each. - for (int32 i = 0; i < parsedName.Length(); i++) { - address_type_kind typeKind; - switch (parsedName[i]) { - case '*': - { - typeKind = DERIVED_TYPE_POINTER; - break; - } - case '&': - { - typeKind = DERIVED_TYPE_REFERENCE; - break; - } - default: - { - return B_BAD_VALUE; - } - - } - - if (derivedType == NULL) { - result = baseType->CreateDerivedAddressType(typeKind, - derivedType); - } else { - result = derivedType->CreateDerivedAddressType(typeKind, - derivedType); - } - - if (result != B_OK) - return result; - typeRef.SetTo(derivedType, true); - } - - _resultType = derivedType; - } else - _resultType = baseType; - - typeRef.Detach(); - - return result; + return false; } diff --git a/src/apps/debugger/source_language/CppLanguage.h b/src/apps/debugger/source_language/CppLanguage.h index 41211d9bbd..9f303781c7 100644 --- a/src/apps/debugger/source_language/CppLanguage.h +++ b/src/apps/debugger/source_language/CppLanguage.h @@ -16,9 +16,8 @@ public: virtual const char* Name() const; - virtual status_t ParseTypeExpression(const BString &expression, - TeamTypeInformation* lookup, - Type*& _resultType) const; +protected: + virtual bool IsModifierValid(char modifier) const; }; diff --git a/src/apps/debugger/user_interface/gui/model/VariablesViewState.cpp b/src/apps/debugger/user_interface/gui/model/VariablesViewState.cpp index e47def9710..99dc79dd69 100644 --- a/src/apps/debugger/user_interface/gui/model/VariablesViewState.cpp +++ b/src/apps/debugger/user_interface/gui/model/VariablesViewState.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2013, Rene Gollent, rene@gollent.com. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -10,6 +11,7 @@ #include "FunctionID.h" #include "StackFrameValues.h" +#include "Type.h" #include "TypeComponentPath.h" @@ -18,15 +20,28 @@ VariablesViewNodeInfo::VariablesViewNodeInfo() : - fNodeExpanded(false) + fNodeExpanded(false), + fCastedType(NULL), + fRendererSettings() { } VariablesViewNodeInfo::VariablesViewNodeInfo(const VariablesViewNodeInfo& other) : - fNodeExpanded(other.fNodeExpanded) + fNodeExpanded(other.fNodeExpanded), + fCastedType(other.fCastedType), + fRendererSettings(other.fRendererSettings) { + if (fCastedType != NULL) + fCastedType->AcquireReference(); +} + + +VariablesViewNodeInfo::~VariablesViewNodeInfo() +{ + if (fCastedType != NULL) + fCastedType->ReleaseReference(); } @@ -34,6 +49,9 @@ VariablesViewNodeInfo& VariablesViewNodeInfo::operator=(const VariablesViewNodeInfo& other) { fNodeExpanded = other.fNodeExpanded; + SetCastedType(other.fCastedType); + fRendererSettings = other.fRendererSettings; + return *this; } @@ -45,6 +63,25 @@ VariablesViewNodeInfo::SetNodeExpanded(bool expanded) } +void +VariablesViewNodeInfo::SetCastedType(Type* type) +{ + if (fCastedType != NULL) + fCastedType->ReleaseReference(); + + fCastedType = type; + if (fCastedType != NULL) + fCastedType->AcquireReference(); +} + + +void +VariablesViewNodeInfo::SetRendererSettings(const BMessage& settings) +{ + fRendererSettings = settings; +} + + // #pragma mark - Key diff --git a/src/apps/debugger/user_interface/gui/model/VariablesViewState.h b/src/apps/debugger/user_interface/gui/model/VariablesViewState.h index 41e927192f..95b5f2996b 100644 --- a/src/apps/debugger/user_interface/gui/model/VariablesViewState.h +++ b/src/apps/debugger/user_interface/gui/model/VariablesViewState.h @@ -1,4 +1,5 @@ /* + * Copyright 2013, Rene Gollent, rene@gollent.com. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -6,12 +7,14 @@ #define VARIABLES_VIEW_STATE_H +#include #include #include class ObjectID; class StackFrameValues; +class Type; class TypeComponentPath; @@ -20,6 +23,7 @@ public: VariablesViewNodeInfo(); VariablesViewNodeInfo( const VariablesViewNodeInfo& other); + virtual ~VariablesViewNodeInfo(); VariablesViewNodeInfo& operator=( const VariablesViewNodeInfo& other); @@ -28,8 +32,19 @@ public: { return fNodeExpanded; } void SetNodeExpanded(bool expanded); + Type* GetCastedType() const + { return fCastedType; } + void SetCastedType(Type* type); + + const BMessage& GetRendererSettings() const + { return fRendererSettings; } + + void SetRendererSettings(const BMessage& settings); + private: bool fNodeExpanded; + Type* fCastedType; + BMessage fRendererSettings; }; 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 17e70f58a1..fbae043de7 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.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. */ @@ -13,6 +13,7 @@ #include +#include #include #include #include @@ -108,6 +109,8 @@ public: fValue(NULL), fValueHandler(NULL), fTableCellRenderer(NULL), + fLastRendererSettings(), + fCastedType(NULL), fComponentPath(NULL), fIsPresentationNode(isPresentationNode), fHidden(false) @@ -128,6 +131,9 @@ public: if (fComponentPath != NULL) fComponentPath->ReleaseReference(); + + if (fCastedType != NULL) + fCastedType->ReleaseReference(); } status_t Init() @@ -194,6 +200,31 @@ public: fValue->AcquireReference(); } + Type* GetCastedType() const + { + return fCastedType; + } + + void SetCastedType(Type* type) + { + if (fCastedType != NULL) + fCastedType->ReleaseReference(); + + fCastedType = type; + if (type != NULL) + fCastedType->AcquireReference(); + } + + const BMessage& GetLastRendererSettings() const + { + return fLastRendererSettings; + } + + void SetLastRendererSettings(const BMessage& settings) + { + fLastRendererSettings = settings; + } + TypeComponentPath* GetPath() const { return fComponentPath; @@ -304,6 +335,8 @@ private: Value* fValue; ValueHandler* fValueHandler; TableCellValueRenderer* fTableCellRenderer; + BMessage fLastRendererSettings; + Type* fCastedType; ChildList fChildren; TypeComponentPath* fComponentPath; bool fIsPresentationNode; @@ -1054,6 +1087,14 @@ VariablesView::VariableTableModel::ValueNodeValueChanged(ValueNode* valueNode) modelNode->SetValueHandler(valueHandler); modelNode->SetTableCellRenderer(renderer); + // we have to restore renderer settings here since until this point + // we don't yet know what renderer is in use. + if (renderer != NULL) { + Settings* settings = renderer->GetSettings(); + if (settings != NULL) + settings->RestoreValues(modelNode->GetLastRendererSettings()); + } + // notify table model listeners NotifyNodeChanged(modelNode); } @@ -1285,16 +1326,20 @@ VariablesView::VariableTableModel::_AddNode(Variable* variable, // is a compound type, mark it hidden if (isOnlyChild && parent != NULL) { ValueNode* parentValueNode = parent->NodeChild()->Node(); - if (parentValueNode != NULL - && parentValueNode->GetType()->ResolveRawType(false)->Kind() - == TYPE_ADDRESS - && nodeChildRawType->Kind() == TYPE_COMPOUND) { - node->SetHidden(true); + if (parentValueNode != NULL) { + if (parentValueNode->GetType()->ResolveRawType(false)->Kind() + == TYPE_ADDRESS) { + type_kind childKind = nodeChildRawType->Kind(); + if (childKind == TYPE_COMPOUND || childKind == TYPE_ARRAY) { + node->SetHidden(true); - // we need to tell the listener about nodes like this so any - // necessary actions can be taken for them (i.e. value resolution), - // since they're otherwise invisible to outsiders. - NotifyNodeHidden(node); + // we need to tell the listener about nodes like this so + // any necessary actions can be taken for them (i.e. value + // resolution), since they're otherwise invisible to + // outsiders. + NotifyNodeHidden(node); + } + } } } @@ -1488,6 +1533,13 @@ VariablesView::MessageReceived(BMessage* message) if (language->ParseTypeExpression(typeExpression, fThread->GetTeam()->DebugInfo(), type) != B_OK) { + BString errorMessage; + errorMessage.SetToFormat("Failed to resolve type %s", + typeExpression.String()); + BAlert* alert = new(std::nothrow) BAlert("Error", + errorMessage.String(), "Close"); + if (alert != NULL) + alert->Go(); break; } @@ -1497,9 +1549,8 @@ VariablesView::MessageReceived(BMessage* message) break; } - // TODO: we need to also persist/restore the casted state - // in VariableViewState node->NodeChild()->SetNode(valueNode); + node->SetCastedType(type); break; } case MSG_SHOW_WATCH_VARIABLE_PROMPT: @@ -1955,6 +2006,13 @@ VariablesView::_AddViewStateDescendentNodeInfos(VariablesViewState* viewState, // add the node's info VariablesViewNodeInfo nodeInfo; nodeInfo.SetNodeExpanded(fVariableTable->IsNodeExpanded(path)); + nodeInfo.SetCastedType(node->GetCastedType()); + TableCellValueRenderer* renderer = node->TableCellRenderer(); + if (renderer != NULL) { + Settings* settings = renderer->GetSettings(); + if (settings != NULL) + nodeInfo.SetRendererSettings(settings->Message()); + } status_t error = viewState->SetNodeInfo(node->GetVariable()->ID(), node->GetPath(), nodeInfo); @@ -1987,6 +2045,25 @@ VariablesView::_ApplyViewStateDescendentNodeInfos(VariablesViewState* viewState, const VariablesViewNodeInfo* nodeInfo = viewState->GetNodeInfo( node->GetVariable()->ID(), node->GetPath()); if (nodeInfo != NULL) { + // NB: if the node info indicates that the node in question + // was being cast to a different type, this *must* be applied + // before any other view state restoration, since it potentially + // changes the child hierarchy under that node. + Type* type = nodeInfo->GetCastedType(); + if (type != NULL) { + ValueNode* valueNode = NULL; + if (TypeHandlerRoster::Default()->CreateValueNode( + node->NodeChild(), type, valueNode) == B_OK) { + node->NodeChild()->SetNode(valueNode); + node->SetCastedType(type); + } + } + + // we don't have a renderer yet so we can't apply the settings + // at this stage. Store them on the model node so we can lazily + // apply them once the value is retrieved. + node->SetLastRendererSettings(nodeInfo->GetRendererSettings()); + fVariableTable->SetNodeExpanded(path, nodeInfo->IsNodeExpanded()); // recurse diff --git a/src/apps/debugger/user_interface/gui/util/GuiSettingsUtils.cpp b/src/apps/debugger/user_interface/gui/util/GuiSettingsUtils.cpp index 0528efb586..6731a698ed 100644 --- a/src/apps/debugger/user_interface/gui/util/GuiSettingsUtils.cpp +++ b/src/apps/debugger/user_interface/gui/util/GuiSettingsUtils.cpp @@ -20,7 +20,7 @@ GuiSettingsUtils::ArchiveSplitView(BMessage& settings, BSplitView* view) if (settings.AddFloat("weight", view->ItemWeight(i)) != B_OK) return B_NO_MEMORY; - if (settings.AddFloat("collapsed", view->IsItemCollapsed(i)) != B_OK) + if (settings.AddBool("collapsed", view->IsItemCollapsed(i)) != B_OK) return B_NO_MEMORY; } diff --git a/src/apps/debugger/user_interface/util/UiUtils.cpp b/src/apps/debugger/user_interface/util/UiUtils.cpp index a27956f9f6..69d75c379a 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.cpp +++ b/src/apps/debugger/user_interface/util/UiUtils.cpp @@ -1,6 +1,6 @@ /* * Copyright 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. */ @@ -11,10 +11,13 @@ #include #include +#include #include #include #include +#include + #include "FunctionInstance.h" #include "Image.h" #include "StackFrame.h" @@ -146,6 +149,100 @@ UiUtils::ImageTypeToString(image_type type, char* buffer, size_t bufferSize) } +/*static*/ const char* +UiUtils::AreaLockingFlagsToString(uint32 flags, char* buffer, + size_t bufferSize) +{ + switch (flags) { + case B_NO_LOCK: + snprintf(buffer, bufferSize, "None"); + break; + case B_LAZY_LOCK: + snprintf(buffer, bufferSize, "Lazy"); + break; + case B_FULL_LOCK: + snprintf(buffer, bufferSize, "Full"); + break; + case B_CONTIGUOUS: + snprintf(buffer, bufferSize, "Contiguous"); + break; + case B_LOMEM: + snprintf(buffer, bufferSize, "Lo-mem"); + break; + case B_32_BIT_FULL_LOCK: + snprintf(buffer, bufferSize, "32-bit Full"); + break; + case B_32_BIT_CONTIGUOUS: + snprintf(buffer, bufferSize, "32-bit Contiguous"); + break; + default: + snprintf(buffer, bufferSize, "Unknown"); + break; + } + + return buffer; +} + + +/*static*/ const BString& +UiUtils::AreaProtectionFlagsToString(uint32 protection, BString& _output) +{ + #undef ADD_AREA_FLAG_IF_PRESENT + #define ADD_AREA_FLAG_IF_PRESENT(flag, protection, name, output) \ + if ((protection & flag) != 0) { \ + _output += name; \ + protection &= ~flag; \ + } + + _output.Truncate(0); + uint32 userFlags = protection & B_USER_PROTECTION; + if ((protection & B_USER_PROTECTION) != 0) { + ADD_AREA_FLAG_IF_PRESENT(B_READ_AREA, protection, "r", _output); + ADD_AREA_FLAG_IF_PRESENT(B_WRITE_AREA, protection, "w", _output); + ADD_AREA_FLAG_IF_PRESENT(B_EXECUTE_AREA, protection, "x", _output); + ADD_AREA_FLAG_IF_PRESENT(B_STACK_AREA, protection, "s", _output); + ADD_AREA_FLAG_IF_PRESENT(B_OVERCOMMITTING_AREA, protection, " overcommitting", + _output); + _output += ", "; + + // if the user versions of these flags are present, + // filter out their kernel equivalents since they're implied. + if ((userFlags & B_READ_AREA) != 0) + protection &= ~B_KERNEL_READ_AREA; + if ((userFlags & B_WRITE_AREA) != 0) + protection &= ~B_KERNEL_WRITE_AREA; + if ((userFlags & B_EXECUTE_AREA) != 0) + protection &= ~B_KERNEL_EXECUTE_AREA; + if ((userFlags & B_STACK_AREA) != 0) + protection &= ~B_KERNEL_STACK_AREA; + } + if ((protection & B_KERNEL_AREA_FLAGS) != 0) { + _output += "kernel:"; + ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_READ_AREA, protection, "r", _output); + ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_WRITE_AREA, protection, "w", + _output); + ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_EXECUTE_AREA, protection, "x", + _output); + ADD_AREA_FLAG_IF_PRESENT(B_KERNEL_STACK_AREA, protection, "s", + _output); + ADD_AREA_FLAG_IF_PRESENT(B_USER_CLONEABLE_AREA, protection, " cloneable", + _output); + ADD_AREA_FLAG_IF_PRESENT(B_SHARED_AREA, protection, " shared", _output); + _output += ", "; + } + + if (protection != 0) { + char buffer[32]; + snprintf(buffer, sizeof(buffer), " Unknown (%#04" B_PRIx32 ")", + protection); + _output += buffer; + } else if (!_output.IsEmpty()) + _output.Truncate(_output.Length() - 2); + + return _output; +} + + /*static*/ const char* UiUtils::ReportNameForTeam(::Team* team, char* buffer, size_t bufferSize) { diff --git a/src/apps/debugger/user_interface/util/UiUtils.h b/src/apps/debugger/user_interface/util/UiUtils.h index 7f6447d06e..69480242b5 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.h +++ b/src/apps/debugger/user_interface/util/UiUtils.h @@ -31,6 +31,10 @@ public: char* buffer, size_t bufferSize); static const char* ImageTypeToString(image_type type, char* buffer, size_t bufferSize); + static const char* AreaLockingFlagsToString(uint32 flags, + char* buffer, size_t bufferSize); + static const BString& AreaProtectionFlagsToString(uint32 protection, + BString& _output); static const char* ReportNameForTeam(::Team* team, char* buffer, size_t bufferSize); diff --git a/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp b/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp index 816fb8965e..7b55b9b2f5 100644 --- a/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp +++ b/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2011, Rene Gollent, rene@gollent.com + * Copyright 2011-2013, Rene Gollent, rene@gollent.com * Distributed under the terms of the MIT License. */ @@ -22,6 +22,9 @@ #include "ValueNodeContainer.h" +static const int64 kMaxStringSize = 64; + + // #pragma mark - BMessageWhatNodeChild @@ -471,12 +474,6 @@ BMessageValueNode::_GetTypeForTypeCode(type_code type, constraints.SetTypeKind(TYPE_COMPOUND); break; - case B_POINTER_TYPE: - typeName = ""; - constraints.SetTypeKind(TYPE_ADDRESS); - constraints.SetBaseTypeName("void"); - break; - case B_RECT_TYPE: typeName = "BRect"; constraints.SetTypeKind(TYPE_COMPOUND); @@ -493,13 +490,30 @@ BMessageValueNode::_GetTypeForTypeCode(type_code type, break; case B_STRING_TYPE: - typeName = ""; - constraints.SetTypeKind(TYPE_ARRAY); - constraints.SetBaseTypeName("char"); - break; + { + typeName = "char"; + constraints.SetTypeKind(TYPE_PRIMITIVE); + Type* baseType = NULL; + status_t result = fLoader->LookupTypeByName(typeName, constraints, + baseType); + if (result != B_OK) + return result; + BReference typeReference(baseType, true); + ArrayType* arrayType; + result = baseType->CreateDerivedArrayType(0, kMaxStringSize, true, + arrayType); + if (result == B_OK) + _type = arrayType; + return result; + break; + } + + case B_POINTER_TYPE: default: - return B_BAD_VALUE; + typeName = ""; + constraints.SetTypeKind(TYPE_ADDRESS); + constraints.SetBaseTypeName("void"); break; } diff --git a/src/apps/debugger/value/value_nodes/CStringValueNode.cpp b/src/apps/debugger/value/value_nodes/CStringValueNode.cpp index f3e4a09792..65cd7f79d9 100644 --- a/src/apps/debugger/value/value_nodes/CStringValueNode.cpp +++ b/src/apps/debugger/value/value_nodes/CStringValueNode.cpp @@ -84,12 +84,18 @@ CStringValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, ValuePieceLocation piece; piece.SetToMemory(addressData.ToUInt64()); + TRACE_LOCALS(" Address found: %#" B_PRIx64 "\n", + addressData.ToUInt64()); + error = valueLoader->LoadStringValue(addressData, maxSize, valueData); if (error != B_OK) return error; piece.size = valueData.Length(); + TRACE_LOCALS(" String value found, length: %" B_PRIu64 "bytes\n", + piece.size); + ValueLocation* stringLocation = new(std::nothrow) ValueLocation( valueLoader->GetArchitecture()->IsBigEndian(), piece); diff --git a/src/apps/deskbar/BarApp.cpp b/src/apps/deskbar/BarApp.cpp index 8ed106714c..cc9a629835 100644 --- a/src/apps/deskbar/BarApp.cpp +++ b/src/apps/deskbar/BarApp.cpp @@ -37,8 +37,6 @@ All rights reserved. #include "BarApp.h" #include -#include -#include #include #include @@ -94,10 +92,11 @@ main() TBarApp::TBarApp() - : BApplication(kDeskbarSignature), - fSettingsFile(NULL), - fClockSettingsFile(NULL), - fPreferencesWindow(NULL) + : + BApplication(kDeskbarSignature), + fSettingsFile(NULL), + fClockSettingsFile(NULL), + fPreferencesWindow(NULL) { InitSettings(); InitIconPreloader(); @@ -131,10 +130,9 @@ TBarApp::TBarApp() // Call UpdatePlacement() after the window is shown because expanded // apps need to resize the window. - if (fBarWindow->Lock()) { - fBarView->UpdatePlacement(); - fBarWindow->Unlock(); - } + fBarWindow->Lock(); + fBarView->UpdatePlacement(); + fBarWindow->Unlock(); // this messenger now targets the barview instead of the // statusview so that all additions to the tray @@ -193,7 +191,7 @@ TBarApp::SaveSettings() prefs.AddBool("vertical", fSettings.vertical); prefs.AddBool("left", fSettings.left); prefs.AddBool("top", fSettings.top); - prefs.AddUInt32("state", fSettings.state); + prefs.AddInt32("state", fSettings.state); prefs.AddFloat("width", fSettings.width); prefs.AddPoint("switcherLoc", fSettings.switcherLoc); prefs.AddBool("showClock", fSettings.showClock); @@ -293,7 +291,7 @@ TBarApp::InitSettings() fDefaultSettings.left); settings.top = prefs.GetBool("top", fDefaultSettings.top); - settings.state = prefs.GetUInt32("state", + settings.state = prefs.GetInt32("state", fDefaultSettings.state); settings.width = prefs.GetFloat("width", fDefaultSettings.width); @@ -435,13 +433,13 @@ TBarApp::MessageReceived(BMessage* message) uint32 flags = 0; message->FindInt32("be:flags", (int32*)&flags); - const char* sig = NULL; - message->FindString("be:signature", &sig); + const char* signature = NULL; + message->FindString("be:signature", &signature); entry_ref ref; message->FindRef("be:ref", &ref); - AddTeam(team, flags, sig, &ref); + AddTeam(team, flags, signature, &ref); break; } @@ -468,10 +466,12 @@ TBarApp::MessageReceived(BMessage* message) case kAlwaysTop: fSettings.alwaysOnTop = !fSettings.alwaysOnTop; - fBarWindow->SetFeel(fSettings.alwaysOnTop ? - B_FLOATING_ALL_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL); + if (fPreferencesWindow != NULL) fPreferencesWindow->PostMessage(kUpdatePreferences); + + fBarWindow->SetFeel(fSettings.alwaysOnTop ? B_FLOATING_ALL_WINDOW_FEEL + : B_NORMAL_WINDOW_FEEL); break; case kAutoRaise: @@ -485,34 +485,44 @@ TBarApp::MessageReceived(BMessage* message) case kAutoHide: fSettings.autoHide = !fSettings.autoHide; + if (fPreferencesWindow != NULL) + fPreferencesWindow->PostMessage(kUpdatePreferences); + fBarWindow->Lock(); fBarView->HideDeskbar(fSettings.autoHide); fBarWindow->Unlock(); - - if (fPreferencesWindow != NULL) - fPreferencesWindow->PostMessage(kUpdatePreferences); break; case kTrackerFirst: fSettings.trackerAlwaysFirst = !fSettings.trackerAlwaysFirst; - fBarWindow->Lock(); - fBarView->PlaceApplicationBar(); - fBarWindow->Unlock(); - if (fPreferencesWindow != NULL) fPreferencesWindow->PostMessage(kUpdatePreferences); + + // if mini mode we don't need to update the view + if (fBarView->MiniState()) + break; + + fBarWindow->Lock(); + fBarView->SaveExpandedItems(); + fBarView->PlaceApplicationBar(); + fBarWindow->Unlock(); break; case kSortRunningApps: fSettings.sortRunningApps = !fSettings.sortRunningApps; - fBarWindow->Lock(); - fBarView->PlaceApplicationBar(); - fBarWindow->Unlock(); - if (fPreferencesWindow != NULL) fPreferencesWindow->PostMessage(kUpdatePreferences); + + // if mini mode we don't need to update the view + if (fBarView->MiniState()) + break; + + fBarWindow->Lock(); + fBarView->SaveExpandedItems(); + fBarView->PlaceApplicationBar(); + fBarWindow->Unlock(); break; case kUnsubscribe: @@ -526,56 +536,81 @@ TBarApp::MessageReceived(BMessage* message) case kSuperExpando: fSettings.superExpando = !fSettings.superExpando; - fBarWindow->Lock(); - fBarView->PlaceApplicationBar(); - fBarWindow->Unlock(); - if (fPreferencesWindow != NULL) fPreferencesWindow->PostMessage(kUpdatePreferences); + + // if mini mode we don't need to update the view + if (fBarView->MiniState()) + break; + + fBarWindow->Lock(); + fBarView->SaveExpandedItems(); + fBarView->PlaceApplicationBar(); + fBarWindow->Unlock(); break; case kExpandNewTeams: fSettings.expandNewTeams = !fSettings.expandNewTeams; - fBarWindow->Lock(); - fBarView->PlaceApplicationBar(); - fBarWindow->Unlock(); - if (fPreferencesWindow != NULL) fPreferencesWindow->PostMessage(kUpdatePreferences); + + // if mini mode we don't need to update the view + if (fBarView->MiniState()) + break; + + fBarWindow->Lock(); + fBarView->SaveExpandedItems(); + fBarView->PlaceApplicationBar(); + fBarWindow->Unlock(); break; case kHideLabels: fSettings.hideLabels = !fSettings.hideLabels; - fBarWindow->Lock(); - fBarView->PlaceApplicationBar(); - fBarWindow->Unlock(); - if (fPreferencesWindow != NULL) fPreferencesWindow->PostMessage(kUpdatePreferences); + + // if mini mode we don't need to update the view + if (fBarView->MiniState()) + break; + + fBarWindow->Lock(); + fBarView->SaveExpandedItems(); + fBarView->PlaceApplicationBar(); + fBarWindow->Unlock(); break; case kResizeTeamIcons: { + int32 oldIconSize = fSettings.iconSize; int32 iconSize; - if (message->FindInt32("be:value", &iconSize) != B_OK) break; fSettings.iconSize = iconSize * kIconSizeInterval; + // pin icon size between min and max values if (fSettings.iconSize < kMinimumIconSize) fSettings.iconSize = kMinimumIconSize; else if (fSettings.iconSize > kMaximumIconSize) fSettings.iconSize = kMaximumIconSize; + // don't resize if icon size hasn't changed + if (fSettings.iconSize == oldIconSize) + break; + ResizeTeamIcons(); + if (fPreferencesWindow != NULL) + fPreferencesWindow->PostMessage(kUpdatePreferences); + + // if mini mode we don't need to update the view if (fBarView->MiniState()) break; fBarWindow->Lock(); + fBarView->SaveExpandedItems(); if (!fBarView->Vertical()) { // Must also resize the Deskbar menu and replicant tray in // horizontal mode @@ -584,9 +619,6 @@ TBarApp::MessageReceived(BMessage* message) } fBarView->PlaceApplicationBar(); fBarWindow->Unlock(); - - if (fPreferencesWindow != NULL) - fPreferencesWindow->PostMessage(kUpdatePreferences); break; } @@ -721,7 +753,7 @@ TBarApp::AddTeam(team_id team, uint32 flags, const char* sig, entry_ref* ref) { if ((flags & B_BACKGROUND_APP) != 0 || strcasecmp(sig, kDeskbarSignature) == 0) { - // it's a background app or Deskbar itself, don't add it + // don't add if a background app or Deskbar itself return; } @@ -835,7 +867,7 @@ TBarApp::RemoveTeam(team_id team) void TBarApp::ResizeTeamIcons() { - for (int32 i = 0; i < sBarTeamInfoList.CountItems(); i++) { + for (int32 i = sBarTeamInfoList.CountItems() - 1; i >= 0; i--) { BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); if ((barInfo->flags & B_BACKGROUND_APP) == 0 && strcasecmp(barInfo->sig, kDeskbarSignature) != 0) { @@ -954,26 +986,26 @@ TBarApp::IconRect() BarTeamInfo::BarTeamInfo(BList* teams, uint32 flags, char* sig, BBitmap* icon, char* name) - : teams(teams), - flags(flags), - sig(sig), - icon(icon), - name(name) + : + teams(teams), + flags(flags), + sig(sig), + icon(icon), + name(name) { - for (int32 i = 0; i < kIconCacheCount; i++) - iconCache[i] = NULL; + _Init(); } BarTeamInfo::BarTeamInfo(const BarTeamInfo &info) - : teams(new BList(*info.teams)), - flags(info.flags), - sig(strdup(info.sig)), - icon(new BBitmap(*info.icon)), - name(strdup(info.name)) + : + teams(new BList(*info.teams)), + flags(info.flags), + sig(strdup(info.sig)), + icon(new BBitmap(*info.icon)), + name(strdup(info.name)) { - for (int32 i = 0; i < kIconCacheCount; i++) - iconCache[i] = NULL; + _Init(); } @@ -985,3 +1017,11 @@ BarTeamInfo::~BarTeamInfo() for (int32 i = 0; i < kIconCacheCount; i++) delete iconCache[i]; } + + +void +BarTeamInfo::_Init() +{ + for (int32 i = 0; i < kIconCacheCount; i++) + iconCache[i] = NULL; +} diff --git a/src/apps/deskbar/BarApp.h b/src/apps/deskbar/BarApp.h index 89627a36e7..62f16b451c 100644 --- a/src/apps/deskbar/BarApp.h +++ b/src/apps/deskbar/BarApp.h @@ -72,7 +72,7 @@ const int32 kMinimumIconSize = 16; const int32 kMaximumIconSize = 96; const int32 kIconSizeInterval = 8; const int32 kIconCacheCount = (kMaximumIconSize - kMinimumIconSize) - / kIconSizeInterval + 1; + / kIconSizeInterval + 1; // update preferences message constant const uint32 kUpdatePreferences = 'Pref'; @@ -93,6 +93,10 @@ public: BarTeamInfo(const BarTeamInfo &info); ~BarTeamInfo(); +private: + void _Init(); + +public: BList* teams; uint32 flags; char* sig; diff --git a/src/apps/deskbar/BarMenuBar.cpp b/src/apps/deskbar/BarMenuBar.cpp index 1383bd68e2..7f3213ee55 100644 --- a/src/apps/deskbar/BarMenuBar.cpp +++ b/src/apps/deskbar/BarMenuBar.cpp @@ -36,14 +36,15 @@ All rights reserved. #include "BarMenuBar.h" -#include - #include +#include #include #include #include "icons.h" +#include "BarMenuTitle.h" +#include "BarView.h" #include "BarWindow.h" #include "DeskbarMenu.h" #include "DeskbarUtils.h" @@ -53,21 +54,62 @@ All rights reserved. const float kSepItemWidth = 5.0f; -TBarMenuBar::TBarMenuBar(TBarView* bar, BRect frame, const char* name) - : BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false), - fBarView(bar), + +// #pragma mark - TSeparatorItem + + +TSeparatorItem::TSeparatorItem() + : + BSeparatorItem() +{ +} + + +void +TSeparatorItem::Draw() +{ + BMenu* menu = Menu(); + if (menu == NULL) + return; + + BRect frame(Frame()); + frame.right = frame.left + kSepItemWidth; + rgb_color base = menu->LowColor(); + + menu->PushState(); + + menu->SetHighColor(tint_color(base, 1.22)); + frame.top--; + // need to expand the frame for some reason + + // stroke a darker line on the left edge + menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()); + frame.left++; + + // fill in background + be_control_look->DrawButtonBackground(menu, frame, frame, base); + + menu->PopState(); +} + + +// #pragma mark - TBarMenuBar + + +TBarMenuBar::TBarMenuBar(BRect frame, const char* name, TBarView* barView) + : + BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false), + fBarView(barView), fAppListMenuItem(NULL), fSeparatorItem(NULL) { SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f); - TDeskbarMenu* beMenu = new TDeskbarMenu(bar); + TDeskbarMenu* beMenu = new TDeskbarMenu(barView); TBarWindow::SetDeskbarMenu(beMenu); - const BBitmap* logoBitmap = AppResSet()->FindBitmap(B_MESSAGE_TYPE, - R_LeafLogoBitmap); - fDeskbarMenuItem = new TBarMenuTitle(frame.Width(), frame.Height(), - logoBitmap, beMenu); + fDeskbarMenuItem = new TBarMenuTitle(0.0f, 0.0f, + AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_LeafLogoBitmap), beMenu); AddItem(fDeskbarMenuItem); } @@ -90,13 +132,13 @@ TBarMenuBar::SmartResize(float width, float height) width -= 1; if (fSeparatorItem != NULL) - fDeskbarMenuItem->SetWidthHeight(width - kSepItemWidth, height); + fDeskbarMenuItem->SetContentSize(width - kSepItemWidth, height); else { int32 count = CountItems(); if (fDeskbarMenuItem) - fDeskbarMenuItem->SetWidthHeight(width / count, height); + fDeskbarMenuItem->SetContentSize(width / count, height); if (fAppListMenuItem) - fAppListMenuItem->SetWidthHeight(width / count, height); + fAppListMenuItem->SetContentSize(width / count, height); } InvalidateLayout(); @@ -146,7 +188,7 @@ TBarMenuBar::RemoveTeamMenu() bool -TBarMenuBar::AddSeperatorItem() +TBarMenuBar::AddSeparatorItem() { if (CountItems() > 1) return false; @@ -154,9 +196,7 @@ TBarMenuBar::AddSeperatorItem() BRect frame(Frame()); delete fSeparatorItem; - fSeparatorItem = new TTeamMenuItem(kSepItemWidth, - frame.Height() - 2, false); - fSeparatorItem->SetEnabled(false); + fSeparatorItem = new TSeparatorItem(); bool added = AddItem(fSeparatorItem); @@ -191,7 +231,7 @@ TBarMenuBar::RemoveSeperatorItem() void TBarMenuBar::Draw(BRect updateRect) { - // want to skip the fancy BMenuBar drawing code. + // skip the fancy BMenuBar drawing code BMenu::Draw(updateRect); } @@ -221,14 +261,15 @@ TBarMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) BPoint loc; uint32 buttons; GetMouse(&loc, &buttons); - // attempt to start DnD tracking - if (message && buttons != 0) { + if (message != NULL && buttons != 0) { + // attempt to start DnD tracking fBarView->CacheDragData(const_cast(message)); MouseDown(loc); } break; } } + BMenuBar::MouseMoved(where, code, message); } diff --git a/src/apps/deskbar/BarMenuBar.h b/src/apps/deskbar/BarMenuBar.h index 75dfd24784..f470d38b1c 100644 --- a/src/apps/deskbar/BarMenuBar.h +++ b/src/apps/deskbar/BarMenuBar.h @@ -42,39 +42,48 @@ All rights reserved. #include - -#include "BarView.h" -#include "BarMenuTitle.h" -#include "TimeView.h" +#include -class TBarMenuBar : public BMenuBar { - public: - TBarMenuBar(TBarView* bar, BRect frame, const char* name); - virtual ~TBarMenuBar(); +class TBarMenuTitle; +class TBarView; - virtual void MouseMoved(BPoint where, uint32 code, - const BMessage* message); - virtual void Draw(BRect); +class TSeparatorItem : public BSeparatorItem { +public: + TSeparatorItem(); - void DrawBackground(BRect); - void SmartResize(float width = -1.0f, float height = -1.0f); - - bool AddTeamMenu(); - bool RemoveTeamMenu(); - - bool AddSeperatorItem(); - bool RemoveSeperatorItem(); - - void InitTrackingHook(bool (* hookfunction)(BMenu*, void*), void* state, - bool both = false); - - private: - TBarView* fBarView; - TBarMenuTitle* fDeskbarMenuItem; - TBarMenuTitle* fAppListMenuItem; - TTeamMenuItem* fSeparatorItem; + virtual void Draw(); }; +class TBarMenuBar : public BMenuBar { +public: + TBarMenuBar(BRect frame, const char* name, + TBarView* barView); + virtual ~TBarMenuBar(); -#endif /* BARMENUBAR_H */ + virtual void MouseMoved(BPoint where, uint32 code, + const BMessage* message); + virtual void Draw(BRect); + + void DrawBackground(BRect); + void SmartResize(float width = -1.0f, + float height = -1.0f); + + bool AddTeamMenu(); + bool RemoveTeamMenu(); + + bool AddSeparatorItem(); + bool RemoveSeperatorItem(); + + void InitTrackingHook( + bool (* hookfunction)(BMenu*, void*), + void* state, bool both = false); + +private: + TBarView* fBarView; + TBarMenuTitle* fDeskbarMenuItem; + TBarMenuTitle* fAppListMenuItem; + TSeparatorItem* fSeparatorItem; +}; + +#endif // BARMENUBAR_H diff --git a/src/apps/deskbar/BarMenuTitle.cpp b/src/apps/deskbar/BarMenuTitle.cpp index cf877a1fb6..50c0d79471 100644 --- a/src/apps/deskbar/BarMenuTitle.cpp +++ b/src/apps/deskbar/BarMenuTitle.cpp @@ -47,12 +47,13 @@ All rights reserved. TBarMenuTitle::TBarMenuTitle(float width, float height, const BBitmap* icon, - BMenu* menu, bool inexpando) - : BMenuItem(menu, new BMessage(B_REFS_RECEIVED)), - fWidth(width), - fHeight(height), - fInExpando(inexpando), - fIcon(icon) + BMenu* menu, bool expando) + : + BMenuItem(menu, new BMessage(B_REFS_RECEIVED)), + fWidth(width), + fHeight(height), + fInExpando(expando), + fIcon(icon) { } @@ -63,7 +64,7 @@ TBarMenuTitle::~TBarMenuTitle() void -TBarMenuTitle::SetWidthHeight(float width, float height) +TBarMenuTitle::SetContentSize(float width, float height) { fWidth = width; fHeight = height; @@ -81,120 +82,51 @@ TBarMenuTitle::GetContentSize(float* width, float* height) void TBarMenuTitle::Draw() { - if (be_control_look == NULL) { - BMenuItem::Draw(); + BMenu* menu = Menu(); + if (menu == NULL) return; - } - // fill background if selected - rgb_color base = Menu()->LowColor(); - BRect rect = Frame(); + BRect frame(Frame()); + rgb_color base = menu->LowColor(); - BRect windowBounds = Menu()->Window()->Bounds(); - if (rect.right > windowBounds.right) - rect.right = windowBounds.right; + menu->PushState(); + BRect windowBounds = menu->Window()->Bounds(); + if (frame.right > windowBounds.right) + frame.right = windowBounds.right; + + // fill in background if (IsSelected()) { - be_control_look->DrawMenuItemBackground(Menu(), rect, rect, base, + be_control_look->DrawMenuItemBackground(menu, frame, frame, base, BControlLook::B_ACTIVATED); - } else { - be_control_look->DrawButtonBackground(Menu(), rect, rect, base); - } + } else + be_control_look->DrawButtonBackground(menu, frame, frame, base); - // draw content + menu->MovePenTo(ContentLocation()); DrawContent(); - // make sure we restore state - Menu()->SetLowColor(base); + menu->PopState(); } void TBarMenuTitle::DrawContent() { + if (fIcon == NULL) + return; + BMenu* menu = Menu(); BRect frame(Frame()); - - if (be_control_look != NULL) { - menu->SetDrawingMode(B_OP_ALPHA); - - if (fIcon != NULL) { - BRect dstRect(fIcon->Bounds()); - dstRect.OffsetTo(frame.LeftTop()); - dstRect.OffsetBy(rintf(((frame.Width() - dstRect.Width()) / 2) - - 1.0f), rintf(((frame.Height() - dstRect.Height()) / 2) - + 2.0f)); - - menu->DrawBitmapAsync(fIcon, dstRect); - } - return; - } - - rgb_color menuColor = menu->LowColor(); - rgb_color dark = tint_color(menuColor, B_DARKEN_1_TINT); - rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT); - - bool inExpandoMode = dynamic_cast(menu) != NULL; - - BRect bounds(menu->Window()->Bounds()); - if (bounds.right < frame.right) - frame.right = bounds.right; - - menu->SetDrawingMode(B_OP_COPY); - - if (!IsSelected() && !menu->IsRedrawAfterSticky()) { - menu->BeginLineArray(8); - menu->AddLine(frame.RightTop(), frame.LeftTop(), light); - menu->AddLine(frame.LeftBottom(), frame.RightBottom(), dark); - menu->AddLine(frame.LeftTop(), - frame.LeftBottom()+BPoint(0, inExpandoMode ? 0 : -1), light); - menu->AddLine(frame.RightBottom(), frame.RightTop(), dark); - if (inExpandoMode) { - frame.top += 1; - menu->AddLine(frame.LeftTop(), frame.RightTop() + BPoint(-1, 0), - light); - } - - menu->EndLineArray(); - - frame.InsetBy(1, 1); - menu->SetHighColor(menuColor); - menu->FillRect(frame); - if (IsSelected()) - menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR)); - else - menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR)); - frame.InsetBy(-1, -1); - if (inExpandoMode) - frame.top -= 1; - } - - ASSERT(IsEnabled()); - if (IsSelected() && !menu->IsRedrawAfterSticky()) { - menu->SetHighColor(tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT)); - menu->FillRect(frame); - - if (menu->IndexOf(this) > 0) { - menu->SetHighColor(tint_color(menuColor, B_DARKEN_4_TINT)); - menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()); - } - - if (IsSelected()) - menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR)); - else - menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR)); - } + BRect iconRect(fIcon->Bounds()); menu->SetDrawingMode(B_OP_ALPHA); + iconRect.OffsetTo(frame.LeftTop()); - if (fIcon != NULL) { - BRect dstRect(fIcon->Bounds()); - dstRect.OffsetTo(frame.LeftTop()); - dstRect.OffsetBy(rintf(((frame.Width() - dstRect.Width()) / 2) - 1.0f), - rintf(((frame.Height() - dstRect.Height()) / 2) - 0.0f)); + float widthOffset = rintf((frame.Width() - iconRect.Width()) / 2); + float heightOffset = rintf((frame.Height() - iconRect.Height()) / 2); + iconRect.OffsetBy(widthOffset - 1.0f, heightOffset + 2.0f); - menu->DrawBitmapAsync(fIcon, dstRect); - } + menu->DrawBitmapAsync(fIcon, iconRect); } diff --git a/src/apps/deskbar/BarMenuTitle.h b/src/apps/deskbar/BarMenuTitle.h index 0a4a9f6b40..f7bcac02ec 100644 --- a/src/apps/deskbar/BarMenuTitle.h +++ b/src/apps/deskbar/BarMenuTitle.h @@ -50,10 +50,10 @@ class BMenu; class TBarMenuTitle : public BMenuItem { public: TBarMenuTitle(float width, float height, const BBitmap* icon, - BMenu* menu, bool inexpando = false); + BMenu* menu, bool expando = false); virtual ~TBarMenuTitle(); - void SetWidthHeight(float width, float height); + void SetContentSize(float width, float height); void Draw(); status_t Invoke(BMessage* message); @@ -70,4 +70,4 @@ private: }; -#endif /* BARMENUTITLE_H */ +#endif // BARMENUTITLE_H diff --git a/src/apps/deskbar/BarSettings.h b/src/apps/deskbar/BarSettings.h index 21b3e1ad14..1b756102c9 100644 --- a/src/apps/deskbar/BarSettings.h +++ b/src/apps/deskbar/BarSettings.h @@ -40,7 +40,7 @@ struct desk_settings { bool vertical; bool left; bool top; - uint32 state; + int32 state; float width; BPoint switcherLoc; bool showClock; diff --git a/src/apps/deskbar/BarView.cpp b/src/apps/deskbar/BarView.cpp index 67ef95f309..483d66e238 100644 --- a/src/apps/deskbar/BarView.cpp +++ b/src/apps/deskbar/BarView.cpp @@ -36,10 +36,6 @@ All rights reserved. #include "BarView.h" -#include -#include -#include - #include #include #include @@ -130,9 +126,10 @@ BarViewMessageFilter::Filter(BMessage* message, BHandler** target) TBarView::TBarView(BRect frame, bool vertical, bool left, bool top, - uint32 state, float) + int32 state, float) : BView(frame, "BarView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW), + fBarApp(static_cast(be_app)), fInlineScrollView(NULL), fBarMenuBar(NULL), fExpandoMenuBar(NULL), @@ -140,7 +137,7 @@ TBarView::TBarView(BRect frame, bool vertical, bool left, bool top, fVertical(vertical), fTop(top), fLeft(left), - fState(static_cast(state)), + fState(state), fRefsRcvdOnly(true), fDragMessage(NULL), fCachedTypesList(NULL), @@ -149,18 +146,32 @@ TBarView::TBarView(BRect frame, bool vertical, bool left, bool top, fLastDragItem(NULL), fMouseFilter(NULL) { + // determine the initial Be menu size + BRect menuFrame(frame); + if (fVertical) + menuFrame.bottom = menuFrame.top + kMenuBarHeight; + else + menuFrame.bottom = menuFrame.top + fBarApp->IconSize() + 4; + + // create and add the Be menu + fBarMenuBar = new TBarMenuBar(menuFrame, "BarMenuBar", this); + AddChild(fBarMenuBar); + + // create and add the status tray fReplicantTray = new TReplicantTray(this, fVertical); fDragRegion = new TDragRegion(this, fReplicantTray); fDragRegion->AddChild(fReplicantTray); if (fTrayLocation != 0) AddChild(fDragRegion); + // create and add the application menubar fExpandoMenuBar = new TExpandoMenuBar(BRect(0, 0, 0, 0), - "ExpandoMenuBar", fVertical); + "ExpandoMenuBar", this, fVertical); fInlineScrollView = new TInlineScrollView(BRect(0, 0, 0, 0), fExpandoMenuBar, fVertical ? B_VERTICAL : B_HORIZONTAL); AddChild(fInlineScrollView); + // If mini mode, hide the application menubar if (state == kMiniState) fInlineScrollView->Hide(); } @@ -279,7 +290,7 @@ TBarView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) if (transit == B_ENTERED_VIEW && EventMask() == 0) SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); - desk_settings* settings = ((TBarApp*)be_app)->Settings(); + desk_settings* settings = fBarApp->Settings(); bool alwaysOnTop = settings->alwaysOnTop; bool autoRaise = settings->autoRaise; bool autoHide = settings->autoHide; @@ -346,7 +357,7 @@ TBarView::MouseDown(BPoint where) } } else { // hide deskbar if required - desk_settings* settings = ((TBarApp*)be_app)->Settings(); + desk_settings* settings = fBarApp->Settings(); bool alwaysOnTop = settings->alwaysOnTop; bool autoRaise = settings->autoRaise; bool autoHide = settings->autoHide; @@ -364,31 +375,15 @@ TBarView::MouseDown(BPoint where) void TBarView::PlaceDeskbarMenu() { - // Calculate the size of the deskbar menu - BRect menuFrame(Bounds()); - if (fVertical) - menuFrame.bottom = menuFrame.top + kMenuBarHeight; - else { - menuFrame.bottom = menuFrame.top - + static_cast(be_app)->IconSize() + 4; - } + float height; + height = fVertical ? kMenuBarHeight : fBarApp->IconSize() + 4; - if (fBarMenuBar == NULL) { - // create the Be menu - fBarMenuBar = new TBarMenuBar(this, menuFrame, "BarMenuBar"); - AddChild(fBarMenuBar); - } else - fBarMenuBar->SmartResize(-1, -1); - - float width = sMinimumWindowWidth; BPoint loc(B_ORIGIN); + float width = sMinimumWindowWidth; if (fState == kFullState) { fBarMenuBar->RemoveTeamMenu(); fBarMenuBar->RemoveSeperatorItem(); - // TODO: Magic constants need explanation - width = 8 + 16 + 8; - fBarMenuBar->SmartResize(width, menuFrame.Height()); loc = Bounds().LeftTop(); } else if (fState == kExpandoState) { fBarMenuBar->RemoveTeamMenu(); @@ -398,7 +393,7 @@ TBarView::PlaceDeskbarMenu() width += 1; } else { // shows apps to the right of bemenu - fBarMenuBar->AddSeperatorItem(); + fBarMenuBar->AddSeparatorItem(); width = floorf(width) / 2 + kSepItemWidth; } loc = Bounds().LeftTop(); @@ -408,7 +403,7 @@ TBarView::PlaceDeskbarMenu() fBarMenuBar->AddTeamMenu(); } - fBarMenuBar->SmartResize(width, menuFrame.Height()); + fBarMenuBar->SmartResize(width, height); fBarMenuBar->MoveTo(loc); } @@ -491,11 +486,10 @@ TBarView::PlaceApplicationBar() } else { // top or bottom expandoFrame.top = 0; - int32 iconSize = static_cast(be_app)->IconSize(); - expandoFrame.bottom = iconSize + 4; + expandoFrame.bottom = fBarApp->IconSize() + 4; if (fBarMenuBar != NULL) - expandoFrame.left = fBarMenuBar->Frame().Width(); + expandoFrame.left = fBarMenuBar->Frame().Width() + 1; if (fTrayLocation != 0 && fDragRegion != NULL) { expandoFrame.right = screenFrame.Width() @@ -512,6 +506,11 @@ TBarView::PlaceApplicationBar() fExpandoMenuBar->MoveTo(0, 0); fExpandoMenuBar->ResizeTo(expandoFrame.Width(), expandoFrame.Height()); + if (!fVertical) { + // Set the max item width based on icon size + fExpandoMenuBar->SetMaxItemWidth(); + } + fExpandoMenuBar->BuildItems(); if (fVertical) ExpandItems(); @@ -519,7 +518,7 @@ TBarView::PlaceApplicationBar() SizeWindow(screenFrame); PositionWindow(screenFrame); fExpandoMenuBar->DoLayout(); - // force menu to autosize + // force menu to resize CheckForScrolling(); Window()->UpdateIfNeeded(); Invalidate(); @@ -531,9 +530,8 @@ TBarView::GetPreferredWindowSize(BRect screenFrame, float* width, float* height) { float windowHeight = 0; float windowWidth = sMinimumWindowWidth; - bool setToHiddenSize = ((TBarApp*)be_app)->Settings()->autoHide - && IsHidden() && !fDragRegion->IsDragging(); - int32 iconSize = static_cast(be_app)->IconSize(); + bool setToHiddenSize = fBarApp->Settings()->autoHide && IsHidden() + && !fDragRegion->IsDragging(); if (setToHiddenSize) { windowHeight = kHiddenDimension; @@ -560,7 +558,7 @@ TBarView::GetPreferredWindowSize(BRect screenFrame, float* width, float* height) } else { // top or bottom, full fExpandoMenuBar->CheckItemSizes(0); - windowHeight = iconSize + 4; + windowHeight = fBarApp->IconSize() + 4; windowWidth = screenFrame.Width(); } } else { @@ -624,12 +622,12 @@ TBarView::CheckForScrolling() void TBarView::SaveSettings() { - desk_settings* settings = ((TBarApp*)be_app)->Settings(); + desk_settings* settings = fBarApp->Settings(); settings->vertical = fVertical; settings->left = fLeft; settings->top = fTop; - settings->state = (uint32)fState; + settings->state = fState; settings->width = 0; fReplicantTray->SaveTimeSettings(); @@ -663,12 +661,13 @@ TBarView::ChangeState(int32 state, bool vertical, bool left, bool top, void TBarView::SaveExpandedItems() { - if (fExpandoMenuBar == NULL || fExpandoMenuBar->CountItems() <= 0) + if (fExpandoMenuBar == NULL) return; // Get a list of the signatures of expanded apps. Can't use // team_id because there can be more than one team per application - for (int32 i = 0; i < fExpandoMenuBar->CountItems(); i++) { + int32 count = fExpandoMenuBar->CountItems(); + for (int32 i = 0; i < count; i++) { TTeamMenuItem* teamItem = dynamic_cast(fExpandoMenuBar->ItemAt(i)); @@ -691,9 +690,10 @@ void TBarView::ExpandItems() { if (fExpandoMenuBar == NULL || !fVertical || fState != kExpandoState - || !static_cast(be_app)->Settings()->superExpando - || fExpandedItems.CountItems() <= 0) + || !fBarApp->Settings()->superExpando + || fExpandedItems.CountItems() <= 0) { return; + } // Start at the 'bottom' of the list working up. // Prevents being thrown off by expanding items. @@ -763,7 +763,7 @@ TBarView::_ChangeState(BMessage* message) } fExpandoMenuBar = new TExpandoMenuBar(BRect(0, 0, 0, 0), - "ExpandoMenuBar", fVertical); + "ExpandoMenuBar", this, fVertical); fInlineScrollView = new TInlineScrollView(BRect(0, 0, 0, 0), fExpandoMenuBar, fVertical ? B_VERTICAL : B_HORIZONTAL); AddChild(fInlineScrollView); diff --git a/src/apps/deskbar/BarView.h b/src/apps/deskbar/BarView.h index 3f9b1445b6..af76aefb2c 100644 --- a/src/apps/deskbar/BarView.h +++ b/src/apps/deskbar/BarView.h @@ -65,7 +65,9 @@ const float kStatusHeight = 22.0f; const float kHiddenDimension = 1.0f; const float kMaxPreventHidingDist = 80.0f; + class BShelf; +class TBarApp; class TBarMenuBar; class TExpandoMenuBar; class TReplicantTray; @@ -73,129 +75,142 @@ class TDragRegion; class TInlineScrollView; class TTeamMenuItem; - class TBarView : public BView { - public: - TBarView(BRect frame, bool vertical, bool left, bool top, - uint32 state, float width); - ~TBarView(); +public: + TBarView(BRect frame, bool vertical, bool left, + bool top, int32 state, float width); + ~TBarView(); - virtual void AttachedToWindow(); - virtual void DetachedFromWindow(); - virtual void Draw(BRect updateRect); - virtual void MessageReceived(BMessage* message); - virtual void MouseMoved(BPoint where, uint32 transit, - const BMessage* dragMessage); - virtual void MouseDown(BPoint where); + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); - void SaveSettings(); - void UpdatePlacement(); - void ChangeState(int32 state, bool vertical, bool left, bool top, - bool aSync = false); - void RaiseDeskbar(bool raise); - void HideDeskbar(bool hide); + virtual void Draw(BRect updateRect); - // window placement methods - bool Vertical() const { return fVertical; }; - bool Left() const { return fLeft; }; - bool Top() const { return fTop; }; - bool AcrossTop() const { return fTop && !fVertical; }; - bool AcrossBottom() const { return !fTop && !fVertical; }; + virtual void MessageReceived(BMessage* message); - // window state methods - bool ExpandoState() const { return fState == kExpandoState; }; - bool FullState() const { return fState == kFullState; }; - bool MiniState() const { return fState == kMiniState; }; - int32 State() const { return fState; }; + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage); + virtual void MouseDown(BPoint where); - // drag and drop methods - void CacheDragData(const BMessage* incoming); - status_t DragStart(); - static bool MenuTrackingHook(BMenu* menu, void* castToThis); - void DragStop(bool full = false); - TrackingHookData* GetTrackingHookData(); - bool Dragging() const; - const BMessage* DragMessage() const; - BObjectList*CachedTypesList() const; - bool AppCanHandleTypes(const char* signature); - void SetDragOverride(bool); - bool DragOverride(); - bool InvokeItem(const char* signature); + void SaveSettings(); - void HandleDeskbarMenu(BMessage* targetmessage); + void UpdatePlacement(); + void ChangeState(int32 state, bool vertical, bool left, + bool top, bool aSync = false); - status_t ItemInfo(int32 id, const char** name, DeskbarShelf* shelf); - status_t ItemInfo(const char* name, int32* id, DeskbarShelf* shelf); + void RaiseDeskbar(bool raise); + void HideDeskbar(bool hide); - bool ItemExists(int32 id, DeskbarShelf shelf); - bool ItemExists(const char* name, DeskbarShelf shelf); + // window placement methods + bool Vertical() const { return fVertical; }; + bool Left() const { return fLeft; }; + bool Top() const { return fTop; }; + bool AcrossTop() const { return fTop && !fVertical; }; + bool AcrossBottom() const + { return !fTop && !fVertical; }; - int32 CountItems(DeskbarShelf shelf); + // window state methods + bool ExpandoState() const + { return fState == kExpandoState; }; + bool FullState() const { return fState == kFullState; }; + bool MiniState() const { return fState == kMiniState; }; + int32 State() const { return fState; }; - status_t AddItem(BMessage* archive, DeskbarShelf shelf, int32* id); - status_t AddItem(BEntry* entry, DeskbarShelf shelf, int32* id); + // drag and drop methods + void CacheDragData(const BMessage* incoming); + status_t DragStart(); + static bool MenuTrackingHook(BMenu* menu, void* castToThis); + void DragStop(bool full = false); + TrackingHookData* GetTrackingHookData(); + bool Dragging() const; + const BMessage* DragMessage() const; + BObjectList* CachedTypesList() const; + bool AppCanHandleTypes(const char* signature); + void SetDragOverride(bool); + bool DragOverride(); + bool InvokeItem(const char* signature); - void RemoveItem(int32 id); - void RemoveItem(const char* name, DeskbarShelf shelf); + void HandleDeskbarMenu(BMessage* targetmessage); - BRect OffsetIconFrame(BRect rect) const; - BRect IconFrame(int32 id) const; - BRect IconFrame(const char* name) const; + status_t ItemInfo(int32 id, const char** name, + DeskbarShelf* shelf); + status_t ItemInfo(const char* name, int32* id, + DeskbarShelf* shelf); - void GetPreferredWindowSize(BRect screenFrame, float* width, - float* height); - void SizeWindow(BRect screenFrame); - void PositionWindow(BRect screenFrame); - void AddExpandedItem(const char* signature); + bool ItemExists(int32 id, DeskbarShelf shelf); + bool ItemExists(const char* name, DeskbarShelf shelf); - void CheckForScrolling(); + int32 CountItems(DeskbarShelf shelf); - TExpandoMenuBar* ExpandoMenuBar() const; - TBarMenuBar* BarMenuBar() const; - TDragRegion* DragRegion() const { return fDragRegion; } - TReplicantTray* ReplicantTray() const { return fReplicantTray; } + status_t AddItem(BMessage* archive, DeskbarShelf shelf, + int32* id); + status_t AddItem(BEntry* entry, DeskbarShelf shelf, + int32* id); - private: - friend class TBarApp; - friend class TDeskbarMenu; - friend class PreferencesWindow; + void RemoveItem(int32 id); + void RemoveItem(const char* name, DeskbarShelf shelf); - status_t SendDragMessage(const char* signature, entry_ref* ref = NULL); + BRect OffsetIconFrame(BRect rect) const; + BRect IconFrame(int32 id) const; + BRect IconFrame(const char* name) const; - void PlaceDeskbarMenu(); - void PlaceTray(bool vertSwap, bool leftSwap); - void PlaceApplicationBar(); - void SaveExpandedItems(); - void RemoveExpandedItems(); - void ExpandItems(); - void _ChangeState(BMessage* message); + void GetPreferredWindowSize(BRect screenFrame, + float* width, float* height); + void SizeWindow(BRect screenFrame); + void PositionWindow(BRect screenFrame); + void AddExpandedItem(const char* signature); - TInlineScrollView* fInlineScrollView; - TBarMenuBar* fBarMenuBar; - TExpandoMenuBar* fExpandoMenuBar; + void CheckForScrolling(); - int32 fTrayLocation; - TDragRegion* fDragRegion; - TReplicantTray* fReplicantTray; + TExpandoMenuBar* ExpandoMenuBar() const; + TBarMenuBar* BarMenuBar() const; + TDragRegion* DragRegion() const { return fDragRegion; } + TReplicantTray* ReplicantTray() const { return fReplicantTray; } - bool fVertical : 1; - bool fTop : 1; - bool fLeft : 1; +private: + friend class TBarApp; + friend class TDeskbarMenu; + friend class PreferencesWindow; - int32 fState; + status_t SendDragMessage(const char* signature, + entry_ref* ref = NULL); - bigtime_t fPulseRate; - bool fRefsRcvdOnly; - BMessage* fDragMessage; - BObjectList*fCachedTypesList; - TrackingHookData fTrackingHookData; + void PlaceDeskbarMenu(); + void PlaceTray(bool vertSwap, bool leftSwap); + void PlaceApplicationBar(); - uint32 fMaxRecentDocs; - uint32 fMaxRecentApps; + void SaveExpandedItems(); + void RemoveExpandedItems(); + void ExpandItems(); - TTeamMenuItem* fLastDragItem; - BList fExpandedItems; - BMessageFilter* fMouseFilter; + void _ChangeState(BMessage* message); + + TBarApp* fBarApp; + TInlineScrollView* fInlineScrollView; + TBarMenuBar* fBarMenuBar; + TExpandoMenuBar* fExpandoMenuBar; + + int32 fTrayLocation; + TDragRegion* fDragRegion; + TReplicantTray* fReplicantTray; + + bool fVertical : 1; + bool fTop : 1; + bool fLeft : 1; + int32 fState; + + bigtime_t fPulseRate; + bool fRefsRcvdOnly; + BMessage* fDragMessage; + BObjectList* fCachedTypesList; + TrackingHookData fTrackingHookData; + + uint32 fMaxRecentDocs; + uint32 fMaxRecentApps; + + TTeamMenuItem* fLastDragItem; + BList fExpandedItems; + BMessageFilter* fMouseFilter; }; @@ -234,4 +249,4 @@ TBarView::CachedTypesList() const } -#endif /* BARVIEW_H */ +#endif // BARVIEW_H diff --git a/src/apps/deskbar/BarWindow.cpp b/src/apps/deskbar/BarWindow.cpp index addf402f8e..08adad8aef 100644 --- a/src/apps/deskbar/BarWindow.cpp +++ b/src/apps/deskbar/BarWindow.cpp @@ -100,6 +100,7 @@ TBarWindow::TBarWindow() desk_settings* settings = ((TBarApp*)be_app)->Settings(); if (settings->alwaysOnTop) SetFeel(B_FLOATING_ALL_WINDOW_FEEL); + fBarView = new TBarView(Bounds(), settings->vertical, settings->left, settings->top, settings->state, settings->width); AddChild(fBarView); diff --git a/src/apps/deskbar/DeskbarMenu.cpp b/src/apps/deskbar/DeskbarMenu.cpp index 24d526505b..60d7567f34 100644 --- a/src/apps/deskbar/DeskbarMenu.cpp +++ b/src/apps/deskbar/DeskbarMenu.cpp @@ -88,7 +88,8 @@ using namespace BPrivate; TDeskbarMenu::TDeskbarMenu(TBarView* barView) - : BNavMenu("DeskbarMenu", B_REFS_RECEIVED, DefaultTarget()), + : + BNavMenu("DeskbarMenu", B_REFS_RECEIVED, DefaultTarget()), fAddState(kStart), fBarView(barView) { diff --git a/src/apps/deskbar/ExpandoMenuBar.cpp b/src/apps/deskbar/ExpandoMenuBar.cpp index 8c60fbe1bc..6460544715 100644 --- a/src/apps/deskbar/ExpandoMenuBar.cpp +++ b/src/apps/deskbar/ExpandoMenuBar.cpp @@ -76,31 +76,25 @@ thread_id TExpandoMenuBar::sMonThread = B_ERROR; BLocker TExpandoMenuBar::sMonLocker("expando monitor"); -TExpandoMenuBar::TExpandoMenuBar(BRect frame, const char* name, bool vertical) +TExpandoMenuBar::TExpandoMenuBar(BRect frame, const char* name, + TBarView* barView, bool vertical) : BMenuBar(frame, name, B_FOLLOW_NONE, vertical ? B_ITEMS_IN_COLUMN : B_ITEMS_IN_ROW), + fBarView(barView), fVertical(vertical), fOverflow(false), fDrawLabel(!static_cast(be_app)->Settings()->hideLabels), fShowTeamExpander(static_cast(be_app)->Settings()->superExpando), fExpandNewTeams(static_cast(be_app)->Settings()->expandNewTeams), fDeskbarMenuWidth(kMinMenuItemWidth), - fBarView(NULL), fPreviousDragTargetItem(NULL), - fLastClickItem(NULL) + fLastClickedItem(NULL), + fClickedExpander(false) { SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f); SetFont(be_plain_font); - if (fVertical) - SetMaxContentWidth(sMinimumWindowWidth); - else { - // Make more room for the icon in horizontal mode - int32 iconSize = static_cast(be_app)->IconSize(); - float maxContentWidth = sMinimumWindowWidth + iconSize - - kMinimumIconSize; - SetMaxContentWidth(maxContentWidth); - } + SetMaxItemWidth(); // top or bottom mode, add deskbar menu and sep for menubar tracking // consistency @@ -124,7 +118,6 @@ TExpandoMenuBar::AttachedToWindow() { BMenuBar::AttachedToWindow(); - fBarView = static_cast(Window())->BarView(); fTeamList.MakeEmpty(); if (fVertical) { @@ -174,21 +167,11 @@ TExpandoMenuBar::MessageReceived(BMessage* message) BBitmap* icon = NULL; message->FindPointer("icon", (void**)&icon); - const char* signature; - if (message->FindString("sig", &signature) == B_OK - &&strcasecmp(signature, kDeskbarSignature) == 0) { - delete teams; - delete icon; - break; - } + const char* signature = NULL; + message->FindString("sig", &signature); - uint32 flags; - if (message->FindInt32("flags", ((int32*) &flags)) == B_OK - && (flags & B_BACKGROUND_APP) != 0) { - delete teams; - delete icon; - break; - } + uint32 flags = 0; + message->FindInt32("flags", ((int32*) &flags)); const char* name = NULL; message->FindString("name", &name); @@ -282,6 +265,9 @@ TExpandoMenuBar::MessageReceived(BMessage* message) void TExpandoMenuBar::MouseDown(BPoint where) { + fClickedExpander = false; + // in case MouseUp() wasn't called + BMessage* message = Window()->CurrentMessage(); BMenuItem* menuItem; TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); @@ -322,30 +308,32 @@ TExpandoMenuBar::MouseDown(BPoint where) // absorb the message } - // Check the bounds of the expand Team icon - if (fVertical && fShowTeamExpander) { - if (item->ExpanderBounds().Contains(where)) { - BAutolock locker(sMonLocker); - // let the update thread wait... - item->ToggleExpandState(true); - // toggle the item - item->Draw(); - return; - // absorb the message - } + int32 buttons = 0; + // check if within expander bounds to expand window items + if (fVertical && fShowTeamExpander + && item->ExpanderBounds().Contains(where) + && message->FindInt32("buttons", &buttons) == B_OK + && buttons == B_PRIMARY_MOUSE_BUTTON) { + // start the animation here, finish on mouse up + fLastClickedItem = item; + fClickedExpander = true; + item->SetArrowDirection(BControlLook::B_RIGHT_DOWN_ARROW); + Invalidate(item->ExpanderBounds()); + return; + // absorb the message } // double-click on an item brings the team to front int32 clicks; if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1 - && item == menuItem && item == fLastClickItem) { + && item == menuItem && item == fLastClickedItem) { be_roster->ActivateApp((addr_t)item->Teams()->ItemAt(0)); // activate this team return; // absorb the message } - fLastClickItem = item; + fLastClickedItem = item; BMenuBar::MouseDown(where); } @@ -353,18 +341,39 @@ TExpandoMenuBar::MouseDown(BPoint where) void TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) { + int32 buttons; + BMessage* currentMessage = Window()->CurrentMessage(); + if (currentMessage == NULL + || currentMessage->FindInt32("buttons", &buttons) != B_OK) { + buttons = 0; + } + if (message == NULL) { // force a cleanup _FinishedDrag(); switch (code) { case B_ENTERED_VIEW: + { + TTeamMenuItem* lastItem + = dynamic_cast(fLastClickedItem); + if (fVertical && fShowTeamExpander && fClickedExpander + && lastItem != NULL && buttons == B_PRIMARY_MOUSE_BUTTON) { + // Started expander animation, exited view then entered + // again, redraw the expanded arrow + lastItem->SetArrowDirection(BControlLook::B_RIGHT_DOWN_ARROW); + Invalidate(lastItem->ExpanderBounds()); + } + break; + } + case B_INSIDE_VIEW: { BMenuItem* menuItem; TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); TWindowMenuItem* windowMenuItem = dynamic_cast(menuItem); + if (item == NULL || menuItem == NULL) { // item is NULL, remove the tooltip and break out fLastMousedOverItem = NULL; @@ -405,26 +414,39 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) break; } + + case B_OUTSIDE_VIEW: + // NOTE: Should not be here, but for the sake of defensive + // programming... fall-through + case B_EXITED_VIEW: + { + TTeamMenuItem* lastItem + = dynamic_cast(fLastClickedItem); + if (fVertical && fShowTeamExpander && fClickedExpander + && lastItem != NULL) { + // Started expander animation, then exited view, + // since we can't track outside mouse movements + // redraw the original expander arrow + lastItem->SetArrowDirection(lastItem->IsExpanded() + ? BControlLook::B_DOWN_ARROW + : BControlLook::B_RIGHT_ARROW); + Invalidate(lastItem->ExpanderBounds()); + } + break; + } } BMenuBar::MouseMoved(where, code, message); return; } - uint32 buttons; - if (Window()->CurrentMessage() == NULL - || Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons) - < B_OK) { - buttons = 0; - } - if (buttons == 0) return; switch (code) { case B_ENTERED_VIEW: // fPreviousDragTargetItem should always be NULL here anyways. - if (fPreviousDragTargetItem) + if (fPreviousDragTargetItem != NULL) _FinishedDrag(); fBarView->CacheDragData(message); @@ -433,7 +455,7 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) case B_OUTSIDE_VIEW: // NOTE: Should not be here, but for the sake of defensive - // programming... + // programming... fall-through case B_EXITED_VIEW: _FinishedDrag(); break; @@ -465,12 +487,36 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) void TExpandoMenuBar::MouseUp(BPoint where) { - if (!fBarView->Dragging()) { - BMenuBar::MouseUp(where); + bool clickedExpander = fClickedExpander; + fClickedExpander = false; + + if (fBarView->Dragging()) { + _FinishedDrag(true); return; + // absorb the message } - _FinishedDrag(true); + TTeamMenuItem* item = TeamItemAtPoint(where, NULL); + TTeamMenuItem* lastItem = dynamic_cast(fLastClickedItem); + if (fVertical && fShowTeamExpander && clickedExpander) { + if (item != NULL && lastItem != NULL && item == lastItem + && item->ExpanderBounds().Contains(where)) { + // Toggle the expanded state + BAutolock locker(sMonLocker); + // let the update thread wait... + item->ToggleExpandState(true); + item->Draw(); + return; + // absorb the message + } else if (lastItem != NULL) { + // User changed their mind, redraw the original expander arrow + lastItem->SetArrowDirection(lastItem->IsExpanded() + ? BControlLook::B_DOWN_ARROW : BControlLook::B_RIGHT_ARROW); + Invalidate(lastItem->ExpanderBounds()); + } + } + + BMenuBar::MouseUp(where); } @@ -506,21 +552,17 @@ TExpandoMenuBar::BuildItems() int32 count = fTeamList.CountItems(); for (int32 i = 0; i < count; i++) { - // add them again + // add items back BarTeamInfo* barInfo = (BarTeamInfo*)fTeamList.ItemAt(i); - if ((barInfo->flags & B_BACKGROUND_APP) == 0 - && strcasecmp(barInfo->sig, kDeskbarSignature) != 0) { - if (settings->trackerAlwaysFirst - && !strcmp(barInfo->sig, kTrackerSignature)) { - AddItem(new TTeamMenuItem(barInfo->teams, barInfo->icon, - barInfo->name, barInfo->sig, itemWidth, itemHeight, - fDrawLabel, fVertical), 0); - } else { - AddItem(new TTeamMenuItem(barInfo->teams, barInfo->icon, - barInfo->name, barInfo->sig, itemWidth, itemHeight, - fDrawLabel, fVertical)); - } - } + TTeamMenuItem* item = new TTeamMenuItem(barInfo->teams, + barInfo->icon, barInfo->name, barInfo->sig, itemWidth, + itemHeight, fDrawLabel, fVertical); + + if (settings->trackerAlwaysFirst + && strcmp(barInfo->sig, kTrackerSignature) == 0) { + AddItem(item, 0); + } else + AddItem(item); } if (CountItems() == 0) { @@ -666,8 +708,9 @@ TExpandoMenuBar::AddTeam(team_id team, const char* signature) void TExpandoMenuBar::RemoveTeam(team_id team, bool partial) { - int32 count = CountItems(); - for (int32 i = 0; i < count; i++) { + TWindowMenuItem* windowItem = NULL; + + for (int32 i = CountItems() - 1; i >= 0; i--) { if (TTeamMenuItem* item = dynamic_cast(ItemAt(i))) { if (item->Teams()->HasItem((void*)(addr_t)team)) { item->Teams()->RemoveItem(team); @@ -676,14 +719,32 @@ TExpandoMenuBar::RemoveTeam(team_id team, bool partial) return; #ifdef DOUBLECLICKBRINGSTOFRONT - if (fLastClickItem == i) - fLastClickItem = -1; + if (fLastClickedItem == i) + fLastClickedItem = -1; #endif + BAutolock locker(sMonLocker); + // make the update thread wait RemoveItem(i); + if (item == fPreviousDragTargetItem) + fPreviousDragTargetItem = NULL; + if (item == fLastMousedOverItem) + fLastMousedOverItem = NULL; + if (item == fLastClickedItem) + fLastClickedItem = NULL; + delete item; + while ((windowItem = dynamic_cast( + ItemAt(i))) != NULL) { + // Also remove window items (if there are any) + RemoveItem(i); + if (windowItem == fLastMousedOverItem) + fLastMousedOverItem = NULL; + if (windowItem == fLastClickedItem) + fLastClickedItem = NULL; + delete windowItem; + } SizeWindow(-1); Window()->UpdateIfNeeded(); - delete item; return; } } @@ -701,15 +762,17 @@ TExpandoMenuBar::CheckItemSizes(int32 delta) - fDeskbarMenuWidth - kSepItemWidth; int32 iconSize = static_cast(be_app)->IconSize(); float iconOnlyWidth = kIconPadding + iconSize + kIconPadding; - float minItemWidth = fDrawLabel ? iconOnlyWidth + kMinMenuItemWidth - : iconOnlyWidth - kIconPadding; - float maxItemWidth = fDrawLabel ? sMinimumWindowWidth + iconSize - - kMinimumIconSize : iconOnlyWidth; + float minItemWidth = fDrawLabel + ? iconOnlyWidth + kMinMenuItemWidth + : iconOnlyWidth - kIconPadding; + float maxItemWidth = fDrawLabel + ? sMinimumWindowWidth + iconSize - kMinimumIconSize + : iconOnlyWidth; float menuWidth = maxItemWidth * CountItems() + fDeskbarMenuWidth + kSepItemWidth; bool reset = false; - float newWidth = 0.0f; + float newWidth = -1.0f; if (delta >= 0 && menuWidth > maxWidth) { fOverflow = true; @@ -723,15 +786,16 @@ TExpandoMenuBar::CheckItemSizes(int32 delta) newWidth = maxItemWidth; } - if (newWidth > maxItemWidth) - newWidth = maxItemWidth; - else if (newWidth < minItemWidth) - newWidth = minItemWidth; - if (reset) { + if (newWidth > maxItemWidth) + newWidth = maxItemWidth; + else if (newWidth < minItemWidth) + newWidth = minItemWidth; + SetMaxContentWidth(newWidth); if (newWidth == maxItemWidth) fOverflow = false; + InvalidateLayout(); for (int32 index = 0; ; index++) { @@ -744,9 +808,8 @@ TExpandoMenuBar::CheckItemSizes(int32 delta) Invalidate(); Window()->UpdateIfNeeded(); + fBarView->CheckForScrolling(); } - - fBarView->CheckForScrolling(); } @@ -819,8 +882,9 @@ TExpandoMenuBar::CheckForSizeOverrun() int32 iconSize = static_cast(be_app)->IconSize(); float iconOnlyWidth = kIconPadding + iconSize + kIconPadding; - float minItemWidth = fDrawLabel ? iconOnlyWidth + kMinMenuItemWidth - : iconOnlyWidth - kIconPadding; + float minItemWidth = fDrawLabel + ? iconOnlyWidth + kMinMenuItemWidth + : iconOnlyWidth - kIconPadding; float menuWidth = minItemWidth * CountItems() + fDeskbarMenuWidth + kSepItemWidth; float maxWidth = fBarView->DragRegion()->Frame().left @@ -830,6 +894,20 @@ TExpandoMenuBar::CheckForSizeOverrun() } +void +TExpandoMenuBar::SetMaxItemWidth() +{ + if (fVertical) + SetMaxContentWidth(sMinimumWindowWidth); + else { + // Make more room for the icon in horizontal mode + int32 iconSize = static_cast(be_app)->IconSize(); + SetMaxContentWidth(sMinimumWindowWidth + iconSize + - kMinimumIconSize); + } +} + + void TExpandoMenuBar::SizeWindow(int32 delta) { diff --git a/src/apps/deskbar/ExpandoMenuBar.h b/src/apps/deskbar/ExpandoMenuBar.h index f23af5dc68..663f8ea9d9 100644 --- a/src/apps/deskbar/ExpandoMenuBar.h +++ b/src/apps/deskbar/ExpandoMenuBar.h @@ -60,64 +60,69 @@ enum drag_and_drop_selection { }; class TExpandoMenuBar : public BMenuBar { - public: - TExpandoMenuBar(BRect frame, const char* name, bool vertical); +public: + TExpandoMenuBar(BRect frame, const char* name, + TBarView* barView, bool vertical); - virtual void AttachedToWindow(); - virtual void DetachedFromWindow(); + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); - virtual void Draw(BRect update); - virtual void DrawBackground(BRect update); + virtual void Draw(BRect update); + virtual void DrawBackground(BRect update); - virtual void MessageReceived(BMessage* message); + virtual void MessageReceived(BMessage* message); - virtual void MouseDown(BPoint where); - virtual void MouseMoved(BPoint where, uint32 code, const BMessage*); - virtual void MouseUp(BPoint where); + virtual void MouseDown(BPoint where); + virtual void MouseMoved(BPoint where, uint32 code, + const BMessage* message); + virtual void MouseUp(BPoint where); - void BuildItems(); + void BuildItems(); - TTeamMenuItem* TeamItemAtPoint(BPoint location, - BMenuItem** _item = NULL); - bool InDeskbarMenu(BPoint) const; + TTeamMenuItem* TeamItemAtPoint(BPoint location, + BMenuItem** _item = NULL); + bool InDeskbarMenu(BPoint) const; - void CheckItemSizes(int32 delta); + void CheckItemSizes(int32 delta); - menu_layout MenuLayout() const; + menu_layout MenuLayout() const; - void SizeWindow(int32 delta); - bool CheckForSizeOverrun(); + void SetMaxItemWidth(); - private: - static int CompareByName(const void* first, const void* second); - static int32 monitor_team_windows(void* arg); + void SizeWindow(int32 delta); + bool CheckForSizeOverrun(); - void AddTeam(BList* team, BBitmap* icon, char* name, char* signature); - void AddTeam(team_id team, const char* signature); - void RemoveTeam(team_id team, bool partial); +private: + static int CompareByName(const void* first, + const void* second); + static int32 monitor_team_windows(void* arg); - void _FinishedDrag(bool invoke = false); + void AddTeam(BList* team, BBitmap* icon, char* name, + char* signature); + void AddTeam(team_id team, const char* signature); + void RemoveTeam(team_id team, bool partial); - bool fVertical : 1; - bool fOverflow : 1; - bool fDrawLabel : 1; - bool fShowTeamExpander : 1; - bool fExpandNewTeams : 1; + void _FinishedDrag(bool invoke = false); - float fDeskbarMenuWidth; +private: + TBarView* fBarView; + bool fVertical : 1; + bool fOverflow : 1; + bool fDrawLabel : 1; + bool fShowTeamExpander : 1; + bool fExpandNewTeams : 1; - TBarView* fBarView; + float fDeskbarMenuWidth; + TTeamMenuItem* fPreviousDragTargetItem; + BMenuItem* fLastMousedOverItem; + BMenuItem* fLastClickedItem; + bool fClickedExpander; + BList fTeamList; - TTeamMenuItem* fPreviousDragTargetItem; - - BMenuItem* fLastMousedOverItem; - BMenuItem* fLastClickItem; - BList fTeamList; - - static bool sDoMonitor; - static thread_id sMonThread; - static BLocker sMonLocker; + static bool sDoMonitor; + static thread_id sMonThread; + static BLocker sMonLocker; }; -#endif /* EXPANDO_MENU_BAR_H */ +#endif // EXPANDO_MENU_BAR_H diff --git a/src/apps/deskbar/InlineScrollView.cpp b/src/apps/deskbar/InlineScrollView.cpp index 5d38f40797..16225a6197 100644 --- a/src/apps/deskbar/InlineScrollView.cpp +++ b/src/apps/deskbar/InlineScrollView.cpp @@ -451,6 +451,17 @@ TInlineScrollView::AttachScrollers() fScrollLimit = fTarget->Bounds().Width() - (frame.Width() - 2 * kScrollerDimension); } + + if (fScrollValue > fScrollLimit) { + // If scroll value is above limit scroll back + float delta = fScrollLimit - fScrollValue; + if (fOrientation == B_VERTICAL) + fTarget->ScrollBy(0, delta); + else + fTarget->ScrollBy(delta, 0); + + fScrollValue = fScrollLimit; + } return; } diff --git a/src/apps/deskbar/ResourceSet.cpp b/src/apps/deskbar/ResourceSet.cpp index 17469b26eb..f80f082cca 100644 --- a/src/apps/deskbar/ResourceSet.cpp +++ b/src/apps/deskbar/ResourceSet.cpp @@ -253,7 +253,7 @@ namespace TResourcePrivate { TypeItem* FindItemByID(int32 id) { - for (int32 i = 0; i < fItems.CountItems(); i++ ) { + for (int32 i = fItems.CountItems() - 1; i >= 0; i--) { TypeItem* it = (TypeItem*)fItems.ItemAt(i); if (it->ID() == id) return it; @@ -263,7 +263,7 @@ namespace TResourcePrivate { TypeItem* FindItemByName(const char* name) { - for (int32 i = 0; i < fItems.CountItems(); i++ ) { + for (int32 i = fItems.CountItems() - 1; i >= 0; i--) { TypeItem* it = (TypeItem*)fItems.ItemAt(i); if (strcmp(it->Name(), name) == 0) return it; @@ -677,8 +677,7 @@ TResourceSet::FindTypeList(type_code type) { BAutolock lock(&fLock); - int32 count = fTypes.CountItems(); - for (int32 i = 0; i < count; i++ ) { + for (int32 i = fTypes.CountItems() - 1; i >= 0; i--) { TypeList* list = (TypeList*)fTypes.ItemAt(i); if (list && list->Type() == type) return list; @@ -731,8 +730,7 @@ TResourceSet::LoadResource(type_code type, int32 id, const char* name, // If a named resource, first look in directories. fLock.Lock(); - int32 count = fDirectories.CountItems(); - for (int32 i = 0; item == 0 && i < count; i++) { + for (int32 i = fDirectories.CountItems() - 1; i >= 0; i--) { BPath* dir = (BPath*)fDirectories.ItemAt(i); if (dir) { fLock.Unlock(); @@ -754,8 +752,7 @@ TResourceSet::LoadResource(type_code type, int32 id, const char* name, if (!item) { // Look through resource objects for data. fLock.Lock(); - int32 count = fResources.CountItems(); - for (int32 i = 0; item == 0 && i < count; i++ ) { + for (int32 i = fResources.CountItems() - 1; i >= 0; i--) { BResources* resource = (BResources*)fResources.ItemAt(i); if (resource) { const void* data = NULL; diff --git a/src/apps/deskbar/ShowHideMenuItem.cpp b/src/apps/deskbar/ShowHideMenuItem.cpp index e195eb7625..4a34af94a8 100644 --- a/src/apps/deskbar/ShowHideMenuItem.cpp +++ b/src/apps/deskbar/ShowHideMenuItem.cpp @@ -113,32 +113,31 @@ TShowHideMenuItem::TeamShowHideCommon(int32 action, const BList* teamList, if (teamList == NULL) return B_BAD_VALUE; - int32 count = teamList->CountItems(); - for (int32 index = 0; index < count; index++) { - team_id team = (addr_t)teamList->ItemAt(index); + for (int32 i = teamList->CountItems() - 1; i >= 0; i--) { + team_id team = (addr_t)teamList->ItemAt(i); switch (action) { case B_MINIMIZE_WINDOW: - do_minimize_team(zoomRect, team, doZoom && index == 0); + do_minimize_team(zoomRect, team, doZoom && i == 0); break; case B_BRING_TO_FRONT: - do_bring_to_front_team(zoomRect, team, doZoom && index == 0); + do_bring_to_front_team(zoomRect, team, doZoom && i == 0); break; case B_QUIT_REQUESTED: - { - BMessenger messenger((char*)NULL, team); - uint32 command = B_QUIT_REQUESTED; - app_info aInfo; - be_roster->GetRunningAppInfo(team, &aInfo); + { + BMessenger messenger((char*)NULL, team); + uint32 command = B_QUIT_REQUESTED; + app_info aInfo; + be_roster->GetRunningAppInfo(team, &aInfo); - if (strcasecmp(aInfo.signature, kTrackerSignature) == 0) - command = 'Tall'; + if (strcasecmp(aInfo.signature, kTrackerSignature) == 0) + command = 'Tall'; - messenger.SendMessage(command); - break; - } + messenger.SendMessage(command); + break; + } } } diff --git a/src/apps/deskbar/StatusView.cpp b/src/apps/deskbar/StatusView.cpp index b25c7af420..5cf934b517 100644 --- a/src/apps/deskbar/StatusView.cpp +++ b/src/apps/deskbar/StatusView.cpp @@ -500,7 +500,7 @@ TReplicantTray::DeleteAddOnSupport() { _SaveSettings(); - for (int32 i = fItemList->CountItems(); i-- > 0 ;) { + for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->RemoveItem(i); if (item) { if (item->isAddOn) @@ -519,7 +519,7 @@ TReplicantTray::DeleteAddOnSupport() DeskbarItemInfo* TReplicantTray::DeskbarItemFor(node_ref& nodeRef) { - for (int32 i = fItemList->CountItems(); i-- > 0 ;) { + for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); if (item == NULL) continue; @@ -535,7 +535,7 @@ TReplicantTray::DeskbarItemFor(node_ref& nodeRef) DeskbarItemInfo* TReplicantTray::DeskbarItemFor(int32 id) { - for (int32 i = fItemList->CountItems(); i-- > 0 ;) { + for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); if (item == NULL) continue; @@ -719,7 +719,7 @@ void TReplicantTray::UnloadAddOn(node_ref* nodeRef, dev_t* device, bool which, bool removeAll) { - for (int32 i = fItemList->CountItems(); i-- > 0 ;) { + for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); if (!item) continue; @@ -783,7 +783,7 @@ TReplicantTray::MoveItem(entry_ref* ref, ino_t toDirectory) // // don't need to change node info as it does not change - for (int32 i = fItemList->CountItems(); i-- > 0 ;) { + for (int32 i = fItemList->CountItems() - 1; i >= 0; i--) { DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->ItemAt(i); if (!item) continue; diff --git a/src/apps/deskbar/Switcher.cpp b/src/apps/deskbar/Switcher.cpp index 59963f66d1..d56b1a0a64 100644 --- a/src/apps/deskbar/Switcher.cpp +++ b/src/apps/deskbar/Switcher.cpp @@ -295,24 +295,6 @@ IsWindowOK(const window_info* windowInfo) } -bool -OKToUse(const TTeamGroup* teamGroup) -{ - if (!teamGroup) - return false; - - // skip background applications - if ((teamGroup->Flags() & B_BACKGROUND_APP) != 0) - return false; - - // skip the Deskbar itself - if (strcasecmp(teamGroup->Signature(), kDeskbarSignature) == 0) - return false; - - return true; -} - - int SmartStrcmp(const char* s1, const char* s2) { @@ -466,7 +448,7 @@ TSwitchManager::TSwitchManager(BPoint point) TSwitchManager::~TSwitchManager() { - for (int32 i = fGroupList.CountItems(); i-- > 0;) { + for (int32 i = fGroupList.CountItems() - 1; i >= 0; i--) { TTeamGroup* teamInfo = static_cast(fGroupList.ItemAt(i)); delete teamInfo; } @@ -489,12 +471,10 @@ TSwitchManager::MessageReceived(BMessage* message) if (tinfo->TeamList()->HasItem((void*)(addr_t)teamID)) { fGroupList.RemoveItem(i); - if (OKToUse(tinfo)) { - fWindow->Redraw(i); - if (i <= fCurrentIndex) { - fCurrentIndex--; - CycleApp(true); - } + fWindow->Redraw(i); + if (i <= fCurrentIndex) { + fCurrentIndex--; + CycleApp(true); } delete tinfo; break; @@ -541,8 +521,7 @@ TSwitchManager::MessageReceived(BMessage* message) signature); fGroupList.AddItem(tinfo); - if (OKToUse(tinfo)) - fWindow->Redraw(fGroupList.CountItems() - 1); + fWindow->Redraw(fGroupList.CountItems() - 1); break; } @@ -551,8 +530,9 @@ TSwitchManager::MessageReceived(BMessage* message) { const char* signature = message->FindString("sig"); team_id team = message->FindInt32("team"); + int32 count = fGroupList.CountItems(); - for (int32 i = 0; i < fGroupList.CountItems(); i++) { + for (int32 i = 0; i < count; i++) { TTeamGroup* tinfo = (TTeamGroup*)fGroupList.ItemAt(i); if (strcasecmp(tinfo->Signature(), signature) == 0) { if (!(tinfo->TeamList()->HasItem((void*)(addr_t)team))) @@ -566,8 +546,9 @@ TSwitchManager::MessageReceived(BMessage* message) case kRemoveTeam: { team_id team = message->FindInt32("team"); + int32 count = fGroupList.CountItems(); - for (int32 i = 0; i < fGroupList.CountItems(); i++) { + for (int32 i = 0; i < count; i++) { TTeamGroup* tinfo = (TTeamGroup*)fGroupList.ItemAt(i); if (tinfo->TeamList()->HasItem((void*)(addr_t)team)) { tinfo->TeamList()->RemoveItem((void*)(addr_t)team); @@ -809,22 +790,6 @@ TSwitchManager::QuickSwitch(BMessage* message) } -int32 -TSwitchManager::CountVisibleGroups() -{ - int32 result = 0; - - int32 count = fGroupList.CountItems(); - for (int32 i = 0; i < count; i++) { - if (!OKToUse((TTeamGroup*)fGroupList.ItemAt(i))) - continue; - - result++; - } - return result; -} - - void TSwitchManager::CycleWindow(bool forward, bool wrap) { @@ -874,31 +839,21 @@ TSwitchManager::CycleApp(bool forward, bool activateNow) bool TSwitchManager::_FindNextValidApp(bool forward) { - int32 startIndex = fCurrentIndex; + if (fGroupList.IsEmpty()) + return false; + int32 max = fGroupList.CountItems(); - - for (;;) { - if (forward) { - fCurrentIndex++; - if (fCurrentIndex >= max) - fCurrentIndex = 0; - } else { - fCurrentIndex--; - if (fCurrentIndex < 0) - fCurrentIndex = max - 1; - } - - if (fCurrentIndex == startIndex) { - // we've gone completely through the list without finding - // a good app. Oh well. - break; - } - - if (OKToUse((TTeamGroup*)fGroupList.ItemAt(fCurrentIndex))) - return true; + if (forward) { + fCurrentIndex++; + if (fCurrentIndex >= max) + fCurrentIndex = 0; + } else { + fCurrentIndex--; + if (fCurrentIndex < 0) + fCurrentIndex = max - 1; } - return false; + return true; } @@ -908,9 +863,6 @@ TSwitchManager::SwitchToApp(int32 previousIndex, int32 newIndex, bool forward) int32 previousSlot = fCurrentSlot; fCurrentIndex = newIndex; - if (!OKToUse((TTeamGroup *)fGroupList.ItemAt(fCurrentIndex))) - _FindNextValidApp(forward); - fCurrentSlot = fWindow->SlotOf(fCurrentIndex); fCurrentWindow = 0; @@ -1039,26 +991,19 @@ TSwitchManager::ActivateApp(bool forceShow, bool allowWorkspaceSwitch) } +/*! + \brief quit all teams in this group +*/ void TSwitchManager::QuitApp() { - // check if we're in the last slot already (the last usable team group) + // we should not be trying to quit an app if we have an empty list + if (fGroupList.IsEmpty()) + return; - TTeamGroup* teamGroup; - int32 count = 0; - - for (int32 i = fCurrentIndex + 1; i < fGroupList.CountItems(); i++) { - teamGroup = (TTeamGroup*)fGroupList.ItemAt(i); - - if (!OKToUse(teamGroup)) - continue; - - count++; - } - - teamGroup = (TTeamGroup*)fGroupList.ItemAt(fCurrentIndex); - - if (count == 0) { + TTeamGroup* teamGroup = (TTeamGroup*)fGroupList.ItemAt(fCurrentIndex); + if (fCurrentIndex == fGroupList.CountItems() - 1) { + // if we're in the last slot already (the last usable team group) // switch to previous app in the list so that we don't jump to // the start of the list (try to keep the same position when // the apps at the current index go away) @@ -1066,12 +1011,11 @@ TSwitchManager::QuitApp() } // send the quit request to all teams in this group - - for (int32 i = teamGroup->TeamList()->CountItems(); i-- > 0;) { + for (int32 i = teamGroup->TeamList()->CountItems() - 1; i >= 0; i--) { team_id team = (addr_t)teamGroup->TeamList()->ItemAt(i); app_info info; if (be_roster->GetRunningAppInfo(team, &info) == B_OK) { - if (!strcasecmp(info.signature, kTrackerSignature)) { + if (strcasecmp(info.signature, kTrackerSignature) == 0) { // Tracker can't be quit this way continue; } @@ -1083,14 +1027,19 @@ TSwitchManager::QuitApp() } +/*! + \brief hide all teams in this group +*/ void TSwitchManager::HideApp() { - // hide all teams in this group + // we should not be trying to hide an app if we have an empty list + if (fGroupList.IsEmpty()) + return; TTeamGroup* teamGroup = (TTeamGroup*)fGroupList.ItemAt(fCurrentIndex); - for (int32 i = teamGroup->TeamList()->CountItems(); i-- > 0;) { + for (int32 i = teamGroup->TeamList()->CountItems() - 1; i >= 0; i--) { team_id team = (addr_t)teamGroup->TeamList()->ItemAt(i); app_info info; if (be_roster->GetRunningAppInfo(team, &info) == B_OK) @@ -1309,8 +1258,8 @@ TBox::MouseDown(BPoint where) int32 newSlot = previousSlot - (kNumSlots - 1); if (newSlot < 0) newSlot = 0; - int32 newIndex = fIconView->IndexAt(newSlot); + int32 newIndex = fIconView->IndexAt(newSlot); fManager->SwitchToApp(previousIndex, newIndex, false); } } @@ -1326,8 +1275,7 @@ TBox::MouseDown(BPoint where) if (newIndex < 0) { // don't have a page full to scroll - int32 valid = fManager->CountVisibleGroups(); - newIndex = fIconView->IndexAt(valid - 1); + newIndex = fManager->GroupList()->CountItems() - 1; } fManager->SwitchToApp(previousIndex, newIndex, true); } @@ -2005,27 +1953,7 @@ TIconView::CenterOn(int32 index) int32 TIconView::ItemAtPoint(BPoint point) const { - float tmpPointVerticalIndex = (point.x / kSlotSize) - kCenterSlot; - if (tmpPointVerticalIndex < 0) - return -1; - - int32 pointVerticalIndex = (int32)tmpPointVerticalIndex; - - for (int32 i = 0, verticalIndex = 0; ; i++) { - - TTeamGroup* teamGroup = (TTeamGroup*)fManager->GroupList()->ItemAt(i); - if (teamGroup == NULL) - break; - - if (!OKToUse(teamGroup)) - continue; - - if (verticalIndex == pointVerticalIndex) - return i; - - verticalIndex++; - } - return -1; + return IndexAt((int32)(point.x / kSlotSize) - kCenterSlot); } @@ -2040,22 +1968,10 @@ TIconView::ScrollTo(BPoint where) int32 TIconView::IndexAt(int32 slot) const { - BList* list = fManager->GroupList(); - int32 count = list->CountItems(); - int32 slotIndex = 0; + if (slot < 0 || slot >= fManager->GroupList()->CountItems()) + return -1; - for (int32 i = 0; i < count; i++) { - TTeamGroup* teamGroup = (TTeamGroup*)list->ItemAt(i); - - if (!OKToUse(teamGroup)) - continue; - - if (slotIndex == slot) { - return i; - } - slotIndex++; - } - return -1; + return slot; } @@ -2071,20 +1987,9 @@ TIconView::SlotOf(int32 index) const BRect TIconView::FrameOf(int32 index) const { - BList* list = fManager->GroupList(); - int32 visible = kCenterSlot - 1; + int32 visible = index + kCenterSlot; // first few slots in view are empty - TTeamGroup* teamGroup; - for (int32 i = 0; i <= index; i++) { - teamGroup = (TTeamGroup*)list->ItemAt(i); - - if (!OKToUse(teamGroup)) - continue; - - visible++; - } - return BRect(visible * kSlotSize, 0, (visible + 1) * kSlotSize - 1, kSlotSize - 1); } @@ -2102,10 +2007,6 @@ TIconView::DrawTeams(BRect update) for (int32 i = 0; i < count; i++) { TTeamGroup* teamGroup = (TTeamGroup*)list->ItemAt(i); - - if (!OKToUse(teamGroup)) - continue; - if (rect.Intersects(update) && teamGroup) { SetDrawingMode(B_OP_ALPHA); SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); diff --git a/src/apps/deskbar/Switcher.h b/src/apps/deskbar/Switcher.h index 7e868f7269..ad5a0a60e5 100644 --- a/src/apps/deskbar/Switcher.h +++ b/src/apps/deskbar/Switcher.h @@ -63,7 +63,6 @@ public: int32 CurrentWindow(); int32 CurrentSlot(); BList* GroupList(); - int32 CountVisibleGroups(); void QuitApp(); void HideApp(); diff --git a/src/apps/deskbar/TeamMenu.cpp b/src/apps/deskbar/TeamMenu.cpp index 7f5a7beef5..4fb8273dff 100644 --- a/src/apps/deskbar/TeamMenu.cpp +++ b/src/apps/deskbar/TeamMenu.cpp @@ -44,12 +44,15 @@ All rights reserved. #include "BarApp.h" #include "BarMenuBar.h" +#include "BarView.h" #include "DeskbarUtils.h" +#include "StatusView.h" #include "TeamMenuItem.h" TTeamMenu::TTeamMenu() - : BMenu("Team Menu") + : + BMenu("Team Menu") { SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f); SetFont(be_plain_font); @@ -68,6 +71,7 @@ void TTeamMenu::AttachedToWindow() { RemoveItems(0, CountItems(), true); + // remove all items BMessenger self(this); BList teamList; @@ -75,39 +79,38 @@ TTeamMenu::AttachedToWindow() TBarView* barview = (dynamic_cast(be_app))->BarView(); bool dragging = barview && barview->Dragging(); - + int32 iconSize = static_cast(be_app)->IconSize(); desk_settings* settings = ((TBarApp*)be_app)->Settings(); + float width = sMinimumWindowWidth - iconSize - 4; + if (settings->sortRunningApps) teamList.SortItems(CompareByName); int32 count = teamList.CountItems(); for (int32 i = 0; i < count; i++) { + // add items back BarTeamInfo* barInfo = (BarTeamInfo*)teamList.ItemAt(i); + TTeamMenuItem* item = new TTeamMenuItem(barInfo->teams, + barInfo->icon, barInfo->name, barInfo->sig, + width, -1, !settings->hideLabels, true); - if (((barInfo->flags & B_BACKGROUND_APP) == 0) - && (strcasecmp(barInfo->sig, kDeskbarSignature) != 0)) { - TTeamMenuItem* item = new TTeamMenuItem(barInfo->teams, - barInfo->icon, barInfo->name, barInfo->sig, -1, -1, - !settings->hideLabels, true); + if (settings->trackerAlwaysFirst + && strcmp(barInfo->sig, kTrackerSignature) == 0) { + AddItem(item, 0); + } else + AddItem(item); - if ((settings->trackerAlwaysFirst) - && (strcmp(barInfo->sig, kTrackerSignature) == 0)) - AddItem(item, 0); - else - AddItem(item); + if (dragging && item != NULL) { + bool canhandle = (dynamic_cast(be_app))->BarView()-> + AppCanHandleTypes(item->Signature()); + if (item->IsEnabled() != canhandle) + item->SetEnabled(canhandle); - if (dragging && item) { - bool canhandle = (dynamic_cast(be_app))->BarView()-> - AppCanHandleTypes(item->Signature()); - if (item->IsEnabled() != canhandle) - item->SetEnabled(canhandle); - - BMenu* menu = item->Submenu(); - if (menu) - menu->SetTrackingHook(barview->MenuTrackingHook, - barview->GetTrackingHookData()); - } + BMenu* menu = item->Submenu(); + if (menu) + menu->SetTrackingHook(barview->MenuTrackingHook, + barview->GetTrackingHookData()); } } @@ -132,9 +135,9 @@ void TTeamMenu::DetachedFromWindow() { TBarView* barView = (dynamic_cast(be_app))->BarView(); - if (barView) { + if (barView != NULL) { BLooper* looper = barView->Looper(); - if (looper->Lock()) { + if (looper != NULL && looper->Lock()) { barView->DragStop(); looper->Unlock(); } @@ -145,9 +148,3 @@ TTeamMenu::DetachedFromWindow() BMessenger self(this); TBarApp::Unsubscribe(self); } - - -void -TTeamMenu::DrawBackground(BRect) -{ -} diff --git a/src/apps/deskbar/TeamMenu.h b/src/apps/deskbar/TeamMenu.h index 244ead8abd..ac3d7cf4a1 100644 --- a/src/apps/deskbar/TeamMenu.h +++ b/src/apps/deskbar/TeamMenu.h @@ -43,21 +43,18 @@ All rights reserved. #include -#include "BarMenuBar.h" -#include "TeamMenuItem.h" - class TTeamMenu : public BMenu { - public: - TTeamMenu(); +public: + TTeamMenu(); - void AttachedToWindow(); - void DetachedFromWindow(); - void DrawBackground(BRect update); + void AttachedToWindow(); + void DetachedFromWindow(); - private: - static int CompareByName(const void* first, const void* second); +private: + static int CompareByName(const void* first, + const void* second); }; -#endif /* TEAMMENU_H */ +#endif // TEAMMENU_H diff --git a/src/apps/deskbar/TeamMenuItem.cpp b/src/apps/deskbar/TeamMenuItem.cpp index 692f3ce17e..8acb8bb6e3 100644 --- a/src/apps/deskbar/TeamMenuItem.cpp +++ b/src/apps/deskbar/TeamMenuItem.cpp @@ -50,6 +50,7 @@ All rights reserved. #include "BarApp.h" #include "BarMenuBar.h" +#include "BarView.h" #include "ExpandoMenuBar.h" #include "ResourceSet.h" #include "ShowHideMenuItem.h" @@ -66,54 +67,22 @@ const float kSwitchWidth = 12; TTeamMenuItem::TTeamMenuItem(BList* team, BBitmap* icon, char* name, char* sig, float width, float height, bool drawLabel, bool vertical) - : BMenuItem(new TWindowMenu(team, sig)) + : + BMenuItem(new TWindowMenu(team, sig)) { - InitData(team, icon, name, sig, width, height, drawLabel, vertical); + _InitData(team, icon, name, sig, width, height, drawLabel, vertical); } TTeamMenuItem::TTeamMenuItem(float width, float height, bool vertical) - : BMenuItem("", NULL) + : + BMenuItem("", NULL) { - InitData(NULL, NULL, strdup(""), strdup(""), width, height, false, + _InitData(NULL, NULL, strdup(""), strdup(""), width, height, false, vertical); } -void -TTeamMenuItem::InitData(BList* team, BBitmap* icon, char* name, char* sig, - float width, float height, bool drawLabel, bool vertical) -{ - fTeam = team; - fIcon = icon; - fName = name; - fSig = sig; - if (fName == NULL) { - char temp[32]; - snprintf(temp, sizeof(temp), "team %ld", (addr_t)team->ItemAt(0)); - fName = strdup(temp); - } - - SetLabel(fName); - - BFont font(be_plain_font); - fLabelWidth = ceilf(font.StringWidth(fName)); - font_height fontHeight; - font.GetHeight(&fontHeight); - fLabelAscent = ceilf(fontHeight.ascent); - fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading); - - fOverrideWidth = width; - fOverrideHeight = height; - fOverriddenSelected = false; - - fVertical = vertical; - fDrawLabel = drawLabel; - - fExpanded = false; -} - - TTeamMenuItem::~TTeamMenuItem() { delete fTeam; @@ -126,16 +95,16 @@ TTeamMenuItem::~TTeamMenuItem() status_t TTeamMenuItem::Invoke(BMessage* message) { - if ((static_cast(be_app))->BarView()->InvokeItem(Signature())) + if (fBarView->InvokeItem(Signature())) { // handles drop on application return B_OK; + } // if the app could not handle the drag message // and we were dragging, then kill the drag // should never get here, disabled item will not invoke - TBarView* barView = (static_cast(be_app))->BarView(); - if (barView && barView->Dragging()) - barView->DragStop(); + if (fBarView != NULL && fBarView->Dragging()) + fBarView->DragStop(); // bring to front or minimize shortcuts uint32 mods = modifiers(); @@ -170,10 +139,10 @@ TTeamMenuItem::SetOverrideSelected(bool selected) } -bool -TTeamMenuItem::HasLabel() const +void +TTeamMenuItem::SetArrowDirection(int32 direction) { - return fDrawLabel; + fArrowDirection = direction; } @@ -184,40 +153,12 @@ TTeamMenuItem::SetHasLabel(bool drawLabel) } -float -TTeamMenuItem::LabelWidth() const -{ - return fLabelWidth; -} - - -BList* -TTeamMenuItem::Teams() const -{ - return fTeam; -} - - -const char* -TTeamMenuItem::Signature() const -{ - return fSig; -} - - -const char* -TTeamMenuItem::Name() const -{ - return fName; -} - - void TTeamMenuItem::GetContentSize(float* width, float* height) { BRect iconBounds; - if (fIcon) + if (fIcon != NULL) iconBounds = fIcon->Bounds(); else iconBounds = BRect(0, 0, kMinimumIconSize - 1, kMinimumIconSize - 1); @@ -252,101 +193,42 @@ TTeamMenuItem::Draw() { BRect frame(Frame()); BMenu* menu = Menu(); + menu->PushState(); + rgb_color menuColor = menu->LowColor(); - TBarView* barView = (static_cast(be_app))->BarView(); + bool canHandle = !fBarView->Dragging() + || fBarView->AppCanHandleTypes(Signature()); + uint32 flags = 0; + if (_IsSelected() && canHandle) + flags |= BControlLook::B_ACTIVATED; - bool canHandle = !barView->Dragging() - || barView->AppCanHandleTypes(Signature()); + uint32 borders = BControlLook::B_TOP_BORDER; + if (fVertical) { + menu->SetHighColor(tint_color(menuColor, B_DARKEN_1_TINT)); + borders |= BControlLook::B_LEFT_BORDER + | BControlLook::B_RIGHT_BORDER; + menu->StrokeLine(frame.LeftBottom(), frame.RightBottom()); + frame.bottom--; - if (be_control_look != NULL) { - uint32 flags = 0; - if (_IsSelected() && canHandle) - flags |= BControlLook::B_ACTIVATED; - - uint32 borders = BControlLook::B_TOP_BORDER; - if (fVertical) { - menu->SetHighColor(tint_color(menuColor, B_DARKEN_1_TINT)); - borders |= BControlLook::B_LEFT_BORDER - | BControlLook::B_RIGHT_BORDER; - menu->StrokeLine(frame.LeftBottom(), frame.RightBottom()); - frame.bottom--; - - be_control_look->DrawMenuBarBackground(menu, frame, frame, - menuColor, flags, borders); - } else { - if (flags & BControlLook::B_ACTIVATED) - menu->SetHighColor(tint_color(menuColor, B_DARKEN_3_TINT)); - else - menu->SetHighColor(tint_color(menuColor, 1.22)); - borders |= BControlLook::B_BOTTOM_BORDER; - menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()); - frame.left++; - - be_control_look->DrawButtonBackground(menu, frame, frame, - menuColor, flags, borders); - } - - menu->MovePenTo(ContentLocation()); - DrawContent(); - menu->PopState(); - return; - } - - // if not selected or being tracked on, fill with gray - if ((!_IsSelected() && !menu->IsRedrawAfterSticky()) || !canHandle - || !IsEnabled()) { - frame.InsetBy(1, 1); - menu->SetHighColor(menuColor); - menu->FillRect(frame); - } - - // draw the gray, unselected item, border - if (!_IsSelected() || !IsEnabled()) { - rgb_color shadow = tint_color(menuColor, B_DARKEN_1_TINT); - rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT); - - frame = Frame(); - - menu->SetHighColor(shadow); - if (fVertical) - menu->StrokeLine(frame.LeftBottom(), frame.RightBottom()); + be_control_look->DrawMenuBarBackground(menu, frame, frame, + menuColor, flags, borders); + } else { + if (flags & BControlLook::B_ACTIVATED) + menu->SetHighColor(tint_color(menuColor, B_DARKEN_3_TINT)); else - menu->StrokeLine(frame.LeftBottom() + BPoint(1, 0), - frame.RightBottom()); + menu->SetHighColor(tint_color(menuColor, 1.22)); + borders |= BControlLook::B_BOTTOM_BORDER; + menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()); + frame.left++; - menu->StrokeLine(frame.RightBottom(), frame.RightTop()); - - menu->SetHighColor(light); - menu->StrokeLine(frame.RightTop() + BPoint(-1, 0), frame.LeftTop()); - if (fVertical) - menu->StrokeLine(frame.LeftTop(), frame.LeftBottom() - + BPoint(0, -1)); - else - menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()); + be_control_look->DrawButtonBackground(menu, frame, frame, + menuColor, flags, borders); } - // if selected or being tracked on, fill with the hilite gray color - if (IsEnabled() && _IsSelected() && !menu->IsRedrawAfterSticky() - && canHandle) { - // fill - menu->SetHighColor(tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT)); - menu->FillRect(frame); - - // these continue the dark grey border on the left or top edge - menu->SetHighColor(tint_color(menuColor, B_DARKEN_4_TINT)); - if (fVertical) { - // dark line at top - menu->StrokeLine(frame.LeftTop(), frame.RightTop()); - } else { - // dark line on the left - menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()); - } - } else - menu->SetLowColor(menuColor); - menu->MovePenTo(ContentLocation()); DrawContent(); + menu->PopState(); } @@ -405,63 +287,9 @@ TTeamMenuItem::DrawContent() DrawContentLabel(); } - // Draw the expandable icon. - TBarView* barView = (static_cast(be_app))->BarView(); if (fVertical && static_cast(be_app)->Settings()->superExpando - && barView->ExpandoState()) { - BRect frame(Frame()); - BRect rect(0, 0, kSwitchWidth, 10); - rect.OffsetTo(BPoint(frame.right - rect.Width(), - ContentLocation().y + ((frame.Height() - rect.Height()) / 2))); - - if (be_control_look != NULL) { - uint32 arrowDirection = fExpanded - ? BControlLook::B_UP_ARROW : BControlLook::B_DOWN_ARROW; - be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(), - arrowDirection, 0, B_DARKEN_3_TINT); - } else { - rgb_color outlineColor = {80, 80, 80, 255}; - rgb_color middleColor = {200, 200, 200, 255}; - - menu->SetDrawingMode(B_OP_OVER); - - if (!fExpanded) { - menu->BeginLineArray(6); - - menu->AddLine(BPoint(rect.left + 3, rect.top + 1), - BPoint(rect.left + 3, rect.bottom - 1), outlineColor); - menu->AddLine(BPoint(rect.left + 3, rect.top + 1), - BPoint(rect.left + 7, rect.top + 5), outlineColor); - menu->AddLine(BPoint(rect.left + 7, rect.top + 5), - BPoint(rect.left + 3, rect.bottom - 1), outlineColor); - - menu->AddLine(BPoint(rect.left + 4, rect.top + 3), - BPoint(rect.left + 4, rect.bottom - 3), middleColor); - menu->AddLine(BPoint(rect.left + 5, rect.top + 4), - BPoint(rect.left + 5, rect.bottom - 4), middleColor); - menu->AddLine(BPoint(rect.left + 5, rect.top + 5), - BPoint(rect.left + 6, rect.top + 5), middleColor); - menu->EndLineArray(); - } else { - // expanded state - - menu->BeginLineArray(6); - menu->AddLine(BPoint(rect.left + 1, rect.top + 3), - BPoint(rect.right - 3, rect.top + 3), outlineColor); - menu->AddLine(BPoint(rect.left + 1, rect.top + 3), - BPoint(rect.left + 5, rect.top + 7), outlineColor); - menu->AddLine(BPoint(rect.left + 5, rect.top + 7), - BPoint(rect.right - 3, rect.top + 3), outlineColor); - - menu->AddLine(BPoint(rect.left + 3, rect.top + 4), - BPoint(rect.right - 5, rect.top + 4), middleColor); - menu->AddLine(BPoint(rect.left + 4, rect.top + 5), - BPoint(rect.right - 6, rect.top + 5), middleColor); - menu->AddLine(BPoint(rect.left + 5, rect.top + 5), - BPoint(rect.left + 5, rect.top + 6), middleColor); - menu->EndLineArray(); - } - } + && fBarView->ExpandoState()) { + DrawExpanderArrow(); } } @@ -501,9 +329,8 @@ TTeamMenuItem::DrawContentLabel() if (!label) label = Label(); - TBarView* barview = (static_cast(be_app))->BarView(); - bool canHandle = !barview->Dragging() - || barview->AppCanHandleTypes(Signature()); + bool canHandle = !fBarView->Dragging() + || fBarView->AppCanHandleTypes(Signature()); if (_IsSelected() && IsEnabled() && canHandle) menu->SetLowColor(tint_color(menu->LowColor(), B_HIGHLIGHT_BACKGROUND_TINT)); @@ -521,10 +348,17 @@ TTeamMenuItem::DrawContentLabel() } -bool -TTeamMenuItem::IsExpanded() +void +TTeamMenuItem::DrawExpanderArrow() { - return fExpanded; + BMenu* menu = Menu(); + BRect frame(Frame()); + BRect rect(0, 0, kSwitchWidth, 10); + + rect.OffsetTo(BPoint(frame.right - rect.Width(), + ContentLocation().y + ((frame.Height() - rect.Height()) / 2))); + be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(), + fArrowDirection, 0, B_DARKEN_3_TINT); } @@ -532,11 +366,13 @@ void TTeamMenuItem::ToggleExpandState(bool resizeWindow) { fExpanded = !fExpanded; + fArrowDirection = fExpanded ? BControlLook::B_DOWN_ARROW + : BControlLook::B_RIGHT_ARROW; if (fExpanded) { // Populate Menu() with the stuff from SubMenu(). TWindowMenu* sub = (static_cast(Submenu())); - if (sub) { + if (sub != NULL) { // force the menu to update it's contents. bool locked = sub->LockLooper(); // if locking the looper failed, the menu is just not visible @@ -567,8 +403,7 @@ TTeamMenuItem::ToggleExpandState(bool resizeWindow) } else { // Remove the goodies from the Menu() that should be in the SubMenu(); TWindowMenu* sub = static_cast(Submenu()); - - if (sub) { + if (sub != NULL) { TExpandoMenuBar* parent = static_cast(Menu()); TWindowMenuItem* windowItem = NULL; @@ -622,6 +457,43 @@ TTeamMenuItem::ExpanderBounds() const } +// #pragma mark - Private methods + + +void +TTeamMenuItem::_InitData(BList* team, BBitmap* icon, char* name, char* sig, + float width, float height, bool drawLabel, bool vertical) +{ + fTeam = team; + fIcon = icon; + fName = name; + fSig = sig; + if (fName == NULL) { + char temp[32]; + snprintf(temp, sizeof(temp), "team %ld", (addr_t)team->ItemAt(0)); + fName = strdup(temp); + } + SetLabel(fName); + fOverrideWidth = width; + fOverrideHeight = height; + fDrawLabel = drawLabel; + fVertical = vertical; + + fBarView = static_cast(be_app)->BarView(); + BFont font(be_plain_font); + fLabelWidth = ceilf(font.StringWidth(fName)); + font_height fontHeight; + font.GetHeight(&fontHeight); + fLabelAscent = ceilf(fontHeight.ascent); + fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading); + + fOverriddenSelected = false; + + fExpanded = false; + fArrowDirection = BControlLook::B_RIGHT_ARROW; +} + + bool TTeamMenuItem::_IsSelected() const { diff --git a/src/apps/deskbar/TeamMenuItem.h b/src/apps/deskbar/TeamMenuItem.h index 9ae1ed1548..4cbfb8522a 100644 --- a/src/apps/deskbar/TeamMenuItem.h +++ b/src/apps/deskbar/TeamMenuItem.h @@ -50,63 +50,76 @@ All rights reserved. class BBitmap; class TTeamMenuItem : public BMenuItem { - public: - TTeamMenuItem(BList* team, BBitmap* icon, char* name, char* sig, - float width = -1.0f, float height = -1.0f, - bool drawLabel = true, bool vertical = true); - TTeamMenuItem(float width = -1.0f, float height = -1.0f, - bool vertical = true); - virtual ~TTeamMenuItem(); +public: + TTeamMenuItem(BList* team, BBitmap* icon, + char* name, char* sig, + float width = -1.0f, float height = -1.0f, + bool drawLabel = true, + bool vertical = true); + TTeamMenuItem(float width = -1.0f, + float height = -1.0f, + bool vertical = true); + virtual ~TTeamMenuItem(); - status_t Invoke(BMessage* msg = NULL); + status_t Invoke(BMessage* msg = NULL); - void SetOverrideWidth(float width); - void SetOverrideHeight(float height); - void SetOverrideSelected(bool selected); + void SetOverrideWidth(float width); + void SetOverrideHeight(float height); + void SetOverrideSelected(bool selected); - bool HasLabel() const; - void SetHasLabel(bool drawLabel); + int32 ArrowDirection() const { return fArrowDirection; }; + void SetArrowDirection(int32 direction); - bool IsExpanded(); - void ToggleExpandState(bool resizeWindow); - BRect ExpanderBounds() const; - TWindowMenuItem* ExpandedWindowItem(int32 id); + bool HasLabel() const { return fDrawLabel; }; + void SetHasLabel(bool drawLabel); - float LabelWidth() const; - BList* Teams() const; - const char* Signature() const; - const char* Name() const; + bool IsExpanded() const { return fExpanded; }; + void ToggleExpandState(bool resizeWindow); + BRect ExpanderBounds() const; + TWindowMenuItem* ExpandedWindowItem(int32 id); - protected: - void GetContentSize(float* width, float* height); - void Draw(); - void DrawContent(); - void DrawContentLabel(); + float LabelWidth() const { return fLabelWidth; }; + BList* Teams() const { return fTeam; }; + const char* Signature() const { return fSig; }; + const char* Name() const { return fName; }; - private: - friend class TExpandoMenuBar; - void InitData(BList* team, BBitmap* icon, char* name, char* sig, - float width = -1.0f, float height = -1.0f, - bool drawLabel = true, bool vertical = true); +protected: + void GetContentSize(float* width, float* height); + void Draw(); + void DrawContent(); + void DrawContentLabel(); + void DrawExpanderArrow(); - bool _IsSelected() const; +private: + friend class TExpandoMenuBar; + void _InitData(BList* team, BBitmap* icon, + char* name, char* sig, + float width = -1.0f, float height = -1.0f, + bool drawLabel = true, + bool vertical = true); - BList* fTeam; - BBitmap* fIcon; - char* fName; - char* fSig; - float fLabelWidth; - float fLabelAscent; - float fLabelDescent; - float fOverrideWidth; - float fOverrideHeight; + bool _IsSelected() const; - bool fDrawLabel; - bool fVertical; +private: + BList* fTeam; + BBitmap* fIcon; + char* fName; + char* fSig; + float fOverrideWidth; + float fOverrideHeight; + bool fDrawLabel; + bool fVertical; - bool fExpanded; - bool fOverriddenSelected; + TBarView* fBarView; + float fLabelWidth; + float fLabelAscent; + float fLabelDescent; + + bool fOverriddenSelected; + + bool fExpanded; + int32 fArrowDirection; }; -#endif /* TEAMMENUITEM_H */ +#endif // TEAMMENUITEM_H diff --git a/src/apps/deskbar/WindowMenuItem.cpp b/src/apps/deskbar/WindowMenuItem.cpp index 21559c581c..b6110d4f24 100644 --- a/src/apps/deskbar/WindowMenuItem.cpp +++ b/src/apps/deskbar/WindowMenuItem.cpp @@ -44,6 +44,7 @@ All rights reserved. #include "BarApp.h" #include "BarMenuBar.h" +#include "BarView.h" #include "ExpandoMenuBar.h" #include "icons.h" #include "ResourceSet.h" diff --git a/src/apps/drivesetup/CreateParametersPanel.cpp b/src/apps/drivesetup/CreateParametersPanel.cpp index 8f3252b014..e08d5ca7fb 100644 --- a/src/apps/drivesetup/CreateParametersPanel.cpp +++ b/src/apps/drivesetup/CreateParametersPanel.cpp @@ -87,7 +87,7 @@ CreateParametersPanel::MessageReceived(BMessage* message) case MSG_SIZE_TEXTCONTROL: { - off_t size = atoi(fSizeTextControl->Text()) * kMegaByte; + off_t size = strtoll(fSizeTextControl->Text(), NULL, 10) * kMegaByte; if (size >= 0 && size <= fSizeSlider->MaxPartitionSize()) fSizeSlider->SetSize(size); else diff --git a/src/apps/musiccollection/MusicCollectionWindow.cpp b/src/apps/musiccollection/MusicCollectionWindow.cpp index 9f729f5871..a84f681707 100644 --- a/src/apps/musiccollection/MusicCollectionWindow.cpp +++ b/src/apps/musiccollection/MusicCollectionWindow.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include diff --git a/src/apps/stylededit/StatusView.cpp b/src/apps/stylededit/StatusView.cpp index a6bdfccf76..ea29c26da8 100644 --- a/src/apps/stylededit/StatusView.cpp +++ b/src/apps/stylededit/StatusView.cpp @@ -26,7 +26,6 @@ #include #include "Constants.h" -#include "StyledEditWindow.h" const float kHorzSpacing = 5.f; @@ -159,7 +158,8 @@ StatusView::MouseDown(BPoint where) if (!fReadOnly) return; - if (where.x < fCellWidth[kPositionCell]) + float left = fCellWidth[kPositionCell] + fCellWidth[kEncodingCell]; + if (where.x < left) return; int32 clicks = 0; @@ -169,11 +169,7 @@ StatusView::MouseDown(BPoint where) return; BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false); - float left = fCellWidth[kPositionCell] + fCellWidth[kEncodingCell]; - if (where.x < left) - StyledEditWindow::PopulateEncodingMenu(menu, fEncoding); - else - menu->AddItem(new BMenuItem(B_TRANSLATE("Unlock file"), + menu->AddItem(new BMenuItem(B_TRANSLATE("Unlock file"), new BMessage(UNLOCK_FILE))); where.x = left; where.y = Bounds().bottom; @@ -203,7 +199,8 @@ StatusView::SetStatus(BMessage* message) || fEncoding.Compare("\xff\xff") == 0 || fEncoding.Compare("UTF-8") == 0) { - fCellText[kEncodingCell] = "UTF-8"; + // do not display default UTF-8 encoding + fCellText[kEncodingCell].Truncate(0); fEncoding.Truncate(0); } else { const BCharacterSet* charset @@ -211,7 +208,6 @@ StatusView::SetStatus(BMessage* message) fCellText[kEncodingCell] = charset != NULL ? charset->GetPrintName() : ""; } - fCellText[kEncodingCell] << " " UTF8_EXPAND_ARROW; } bool modified = false; diff --git a/src/apps/stylededit/StyledEditView.cpp b/src/apps/stylededit/StyledEditView.cpp index 9c8936919e..883550d5a7 100644 --- a/src/apps/stylededit/StyledEditView.cpp +++ b/src/apps/stylededit/StyledEditView.cpp @@ -32,9 +32,13 @@ using namespace BPrivate; StyledEditView::StyledEditView(BRect viewFrame, BRect textBounds, BHandler* handler) - : BTextView(viewFrame, "textview", textBounds, - B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW) -{ + : + BTextView(viewFrame, "textview", textBounds, B_FOLLOW_ALL, + B_FRAME_EVENTS | B_WILL_DRAW) +{ + SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + SetLowColor(ViewColor()); + fMessenger = new BMessenger(handler); fSuppressChanges = false; } @@ -46,6 +50,45 @@ StyledEditView::~StyledEditView() } + +void +StyledEditView::FrameResized(float width, float height) +{ + BTextView::FrameResized(width, height); + + if (DoesWordWrap()) { + BRect textRect; + textRect = Bounds(); + textRect.OffsetTo(B_ORIGIN); + textRect.InsetBy(TEXT_INSET, TEXT_INSET); + SetTextRect(textRect); + } +} + + +void +StyledEditView::DeleteText(int32 start, int32 finish) +{ + if (!fSuppressChanges) + fMessenger-> SendMessage(TEXT_CHANGED); + + BTextView::DeleteText(start, finish); + _UpdateStatus(); +} + + +void +StyledEditView::InsertText(const char* text, int32 length, int32 offset, + const text_run_array* runs) +{ + if (!fSuppressChanges) + fMessenger->SendMessage(TEXT_CHANGED); + + BTextView::InsertText(text, length, offset, runs); + _UpdateStatus(); +} + + void StyledEditView::Select(int32 start, int32 finish) { @@ -174,44 +217,6 @@ StyledEditView::GetEncoding() const } -void -StyledEditView::DeleteText(int32 start, int32 finish) -{ - if (!fSuppressChanges) - fMessenger-> SendMessage(TEXT_CHANGED); - - BTextView::DeleteText(start, finish); - _UpdateStatus(); -} - - -void -StyledEditView::InsertText(const char* text, int32 length, int32 offset, - const text_run_array* runs) -{ - if (!fSuppressChanges) - fMessenger->SendMessage(TEXT_CHANGED); - - BTextView::InsertText(text, length, offset, runs); - _UpdateStatus(); -} - - -void -StyledEditView::FrameResized(float width, float height) -{ - BTextView::FrameResized(width, height); - - if (DoesWordWrap()) { - BRect textRect; - textRect = Bounds(); - textRect.OffsetTo(B_ORIGIN); - textRect.InsetBy(TEXT_INSET, TEXT_INSET); - SetTextRect(textRect); - } -} - - void StyledEditView::_UpdateStatus() { @@ -239,4 +244,3 @@ StyledEditView::_UpdateStatus() message->AddString("encoding", fEncoding.String()); fMessenger->SendMessage(message); } - diff --git a/src/apps/stylededit/StyledEditView.h b/src/apps/stylededit/StyledEditView.h index 951c0ead39..a61cc77ba2 100644 --- a/src/apps/stylededit/StyledEditView.h +++ b/src/apps/stylededit/StyledEditView.h @@ -14,40 +14,41 @@ #include #include + class BFile; class BHandler; class BMessenger; class BPositionIO; - class StyledEditView : public BTextView { - public: +public: StyledEditView(BRect viewframe, BRect textframe, BHandler* handler); - virtual ~StyledEditView(); + virtual ~StyledEditView(); - virtual void Select(int32 start, int32 finish); - virtual void DeleteText(int32 start, int32 finish); - virtual void FrameResized(float width, float height); - virtual void InsertText(const char* text, int32 length, int32 offset, + virtual void FrameResized(float width, float height); + virtual void DeleteText(int32 start, int32 finish); + virtual void InsertText(const char* text, int32 length, + int32 offset, const text_run_array* runs = NULL); + virtual void Select(int32 start, int32 finish); - void Reset(); - void SetSuppressChanges(bool suppressChanges); - status_t GetStyledText(BPositionIO* stream, + void Reset(); + void SetSuppressChanges(bool suppressChanges); + status_t GetStyledText(BPositionIO* stream, const char* forceEncoding = NULL); - status_t WriteStyledEditFile(BFile* file); + status_t WriteStyledEditFile(BFile* file); - void SetEncoding(uint32 encoding); - uint32 GetEncoding() const; + void SetEncoding(uint32 encoding); + uint32 GetEncoding() const; - private: - void _UpdateStatus(); +private: + void _UpdateStatus(); - BMessenger *fMessenger; - bool fSuppressChanges; - BString fEncoding; + BMessenger* fMessenger; + bool fSuppressChanges; + BString fEncoding; }; -#endif // STYLED_EDIT_VIEW_H +#endif // STYLED_EDIT_VIEW_H diff --git a/src/apps/stylededit/StyledEditWindow.cpp b/src/apps/stylededit/StyledEditWindow.cpp index 03b79a35a1..cf0e856537 100644 --- a/src/apps/stylededit/StyledEditWindow.cpp +++ b/src/apps/stylededit/StyledEditWindow.cpp @@ -47,6 +47,7 @@ #include #include #include +#include using namespace BPrivate; @@ -598,9 +599,8 @@ StyledEditWindow::MenusBeginning() BMenu* menu = fCurrentFontItem->Submenu(); if (menu != NULL) { BMenuItem* item = menu->FindMarked(); - if (item != NULL) { + if (item != NULL) item->SetMarked(false); - } } } @@ -622,9 +622,10 @@ StyledEditWindow::MenusBeginning() rgb_color color = BLACK; bool sameColor; fTextView->GetFontAndColor(&font, &sameProperties, &color, &sameColor); + color.alpha = 255; - if (sameColor && color.alpha == 255) { - // select the current color + if (sameColor) { + // mark the menu according to the current color if (color.red == 0) { if (color.green == 0) { if (color.blue == 0) { @@ -849,6 +850,11 @@ StyledEditWindow::SaveAs(BMessage* message) if (message != NULL) fSavePanel->SetMessage(message); + // Move the save panel to the middle of the window + fSavePanel->Window()->MoveTo(Frame().LeftTop().x + Frame().Width() / 2 + - fSavePanel->Window()->Frame().Width() / 2, + Frame().LeftTop().y + Frame().Height() / 4); + fSavePanel->Show(); return B_OK; } @@ -1086,7 +1092,7 @@ StyledEditWindow::_InitWindow(uint32 encoding) textBounds.OffsetTo(B_ORIGIN); textBounds.InsetBy(TEXT_INSET, TEXT_INSET); - fTextView= new StyledEditView(viewFrame, textBounds, this); + fTextView = new StyledEditView(viewFrame, textBounds, this); fTextView->SetDoesUndo(true); fTextView->SetStylable(true); fTextView->SetEncoding(encoding); @@ -1211,8 +1217,8 @@ StyledEditWindow::_InitWindow(uint32 encoding) fFontColorMenu->SetRadioMode(true); fFontMenu->AddItem(fFontColorMenu); - fFontColorMenu->AddItem(fBlackItem = new BMenuItem(B_TRANSLATE("Black"), - new BMessage(FONT_COLOR))); + fFontColorMenu->AddItem(fBlackItem = new ColorMenuItem(B_TRANSLATE("Black"), + BLACK, new BMessage(FONT_COLOR))); fBlackItem->SetMarked(true); fFontColorMenu->AddItem(fRedItem = new ColorMenuItem(B_TRANSLATE("Red"), RED, new BMessage(FONT_COLOR))); @@ -1222,10 +1228,12 @@ StyledEditWindow::_InitWindow(uint32 encoding) BLUE, new BMessage(FONT_COLOR))); fFontColorMenu->AddItem(fCyanItem = new ColorMenuItem(B_TRANSLATE("Cyan"), CYAN, new BMessage(FONT_COLOR))); - fFontColorMenu->AddItem(fMagentaItem = new ColorMenuItem(B_TRANSLATE("Magenta"), - MAGENTA, new BMessage(FONT_COLOR))); - fFontColorMenu->AddItem(fYellowItem = new ColorMenuItem(B_TRANSLATE("Yellow"), - YELLOW, new BMessage(FONT_COLOR))); + fFontColorMenu->AddItem(fMagentaItem + = new ColorMenuItem(B_TRANSLATE("Magenta"), MAGENTA, + new BMessage(FONT_COLOR))); + fFontColorMenu->AddItem(fYellowItem + = new ColorMenuItem(B_TRANSLATE("Yellow"), YELLOW, + new BMessage(FONT_COLOR))); fFontMenu->AddSeparatorItem(); // "Bold" & "Italic" menu items @@ -1293,7 +1301,7 @@ StyledEditWindow::_InitWindow(uint32 encoding) BMessage *message = new BMessage(MENU_RELOAD); message->AddString("encoding", "auto"); - menu->AddItem(fEncodingItem = new BMenuItem(PopulateEncodingMenu( + menu->AddItem(fEncodingItem = new BMenuItem(_PopulateEncodingMenu( new BMenu(B_TRANSLATE("Text encoding")), "UTF-8"), message)); fEncodingItem->SetEnabled(false); @@ -1467,12 +1475,11 @@ StyledEditWindow::_ReloadDocument(BMessage* message) entry_ref ref; const char* name; - if (fSaveMessage == NULL || message == NULL) + if (fSaveMessage == NULL || message == NULL + || fSaveMessage->FindRef("directory", &ref) != B_OK + || fSaveMessage->FindString("name", &name) != B_OK) return; - fSaveMessage->FindRef("directory", &ref); - fSaveMessage->FindString("name", &name); - BDirectory dir(&ref); status_t status = dir.InitCheck(); BEntry entry; @@ -1500,13 +1507,27 @@ StyledEditWindow::_ReloadDocument(BMessage* message) return; } + const BCharacterSet* charset + = BCharacterSetRoster::GetCharacterSetByFontID( + fTextView->GetEncoding()); const char* forceEncoding = NULL; if (message->FindString("encoding", &forceEncoding) != B_OK) { - const BCharacterSet* charset - = BCharacterSetRoster::GetCharacterSetByFontID( - fTextView->GetEncoding()); if (charset != NULL) forceEncoding = charset->GetName(); + } else { + if (charset != NULL) { + // UTF8 id assumed equal to -1 + const uint32 idUTF8 = (uint32)-1; + uint32 id = charset->GetConversionID(); + if (strcmp(forceEncoding, "next") == 0) + id = id == B_MS_WINDOWS_1250_CONVERSION ? idUTF8 : id + 1; + else if (strcmp(forceEncoding, "previous") == 0) + id = id == idUTF8 ? B_MS_WINDOWS_1250_CONVERSION : id - 1; + const BCharacterSet* newCharset + = BCharacterSetRoster::GetCharacterSetByConversionID(id); + if (newCharset != NULL) + forceEncoding = newCharset->GetName(); + } } BScrollBar* vertBar = fScrollView->ScrollBar(B_VERTICAL); @@ -1826,6 +1847,10 @@ StyledEditWindow::_ShowStatistics() BAlert* alert = new BAlert("Statistics", result, B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_INFO_ALERT); alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); + // Move the alert to the middle of the window + alert->MoveTo(Frame().LeftTop().x + Frame().Width() / 2 + - alert->Frame().Width() / 2, + Frame().LeftTop().y + Frame().Height() / 4); return alert->Go(); } @@ -1881,13 +1906,17 @@ StyledEditWindow::_ShowAlert(const BString& text, const BString& label, BAlert* alert = new BAlert("Alert", text.String(), label.String(), button2, button3, B_WIDTH_AS_USUAL, spacing, type); alert->SetShortcut(0, B_ESCAPE); + // Move the alert to the middle of the window + alert->MoveTo(Frame().LeftTop().x + Frame().Width() / 2 + - alert->Frame().Width() / 2, + Frame().LeftTop().y + Frame().Height() / 4); return alert->Go(); } BMenu* -StyledEditWindow::PopulateEncodingMenu(BMenu* menu, const char* currentEncoding) +StyledEditWindow::_PopulateEncodingMenu(BMenu* menu, const char* currentEncoding) { menu->SetRadioMode(true); BString encoding(currentEncoding); @@ -1918,6 +1947,13 @@ StyledEditWindow::PopulateEncodingMenu(BMenu* menu, const char* currentEncoding) message->AddString("encoding", "auto"); menu->AddItem(new BMenuItem(B_TRANSLATE("Autodetect"), message)); + message = new BMessage(MENU_RELOAD); + message->AddString("encoding", "next"); + AddShortcut(B_PAGE_DOWN, B_OPTION_KEY, message); + message = new BMessage(MENU_RELOAD); + message->AddString("encoding", "previous"); + AddShortcut(B_PAGE_UP, B_OPTION_KEY, message); + return menu; } diff --git a/src/apps/stylededit/StyledEditWindow.h b/src/apps/stylededit/StyledEditWindow.h index af8dc04f4b..bf239a6e84 100644 --- a/src/apps/stylededit/StyledEditWindow.h +++ b/src/apps/stylededit/StyledEditWindow.h @@ -49,8 +49,6 @@ public: bool caseSensitive); bool IsDocumentEntryRef(const entry_ref* ref); - static BMenu* PopulateEncodingMenu(BMenu* menu, - const char* encoding); private: void _InitWindow(uint32 encoding = 0); void _LoadAttrs(); @@ -79,6 +77,8 @@ private: const BString& label, const BString& label2, const BString& label3, alert_type type) const; + BMenu* _PopulateEncodingMenu(BMenu* menu, + const char* encoding); // node monitoring helper class _NodeMonitorSuspender { diff --git a/src/apps/terminal/AppearPrefView.cpp b/src/apps/terminal/AppearPrefView.cpp index 75a0e7127a..fa4c86a460 100644 --- a/src/apps/terminal/AppearPrefView.cpp +++ b/src/apps/terminal/AppearPrefView.cpp @@ -399,6 +399,8 @@ AppearancePrefView::_SetCurrentColorScheme() } for (int32 i = 0; i < fColorSchemeField->Menu()->CountItems(); i++) { + if (currentSchemeName == NULL) + break; BMenuItem* item = fColorSchemeField->Menu()->ItemAt(i); if (strcmp(item->Label(), currentSchemeName) == 0) { item->SetMarked(true); diff --git a/src/apps/terminal/BasicTerminalBuffer.cpp b/src/apps/terminal/BasicTerminalBuffer.cpp index f21124de47..f5bcd6199a 100644 --- a/src/apps/terminal/BasicTerminalBuffer.cpp +++ b/src/apps/terminal/BasicTerminalBuffer.cpp @@ -429,7 +429,8 @@ BasicTerminalBuffer::FindWord(const TermPos& pos, // find the beginning TermPos start(x, y); - TermPos end(x + (IS_WIDTH(line->cells[x].attributes) ? 2 : 1), y); + TermPos end(x + (IS_WIDTH(line->cells[x].attributes) + ? FULL_WIDTH : HALF_WIDTH), y); while (true) { if (--x < 0) { // Hit the beginning of the line -- continue at the end of the @@ -470,7 +471,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos, if (classifier->Classify(line->cells[x].character) != type) break; - x += IS_WIDTH(line->cells[x].attributes) ? 2 : 1; + x += IS_WIDTH(line->cells[x].attributes) ? FULL_WIDTH : HALF_WIDTH; end.SetTo(x, y); } @@ -606,14 +607,13 @@ BasicTerminalBuffer::Find(const char* _pattern, const TermPos& start, void -BasicTerminalBuffer::InsertChar(UTF8Char c, uint32 width) +BasicTerminalBuffer::InsertChar(UTF8Char c) { //debug_printf("BasicTerminalBuffer::InsertChar('%.*s' (%d), %#lx)\n", //(int)c.ByteCount(), c.bytes, c.bytes[0], attributes); - if ((int32)width == FULL_WIDTH) - fAttributes |= A_WIDTH; + int32 width = c.IsFullWidth() ? FULL_WIDTH : HALF_WIDTH; - if (fSoftWrappedCursor || fCursor.x + (int32)width > fWidth) + if (fSoftWrappedCursor || (fCursor.x + width) > fWidth) _SoftBreakLine(); else _PadLineToCursor(); @@ -625,7 +625,8 @@ BasicTerminalBuffer::InsertChar(UTF8Char c, uint32 width) TerminalLine* line = _LineAt(fCursor.y); line->cells[fCursor.x].character = c; - line->cells[fCursor.x].attributes = fAttributes; + line->cells[fCursor.x].attributes + = fAttributes | (width == FULL_WIDTH ? A_WIDTH : 0); if (line->length < fCursor.x + width) line->length = fCursor.x + width; @@ -645,10 +646,13 @@ BasicTerminalBuffer::InsertChar(UTF8Char c, uint32 width) void -BasicTerminalBuffer::FillScreen(UTF8Char c, uint32 width, uint32 attributes) +BasicTerminalBuffer::FillScreen(UTF8Char c, uint32 attributes) { - if ((int32)width == FULL_WIDTH) + uint32 width = HALF_WIDTH; + if (c.IsFullWidth()) { attributes |= A_WIDTH; + width = FULL_WIDTH; + } fSoftWrappedCursor = false; @@ -1724,7 +1728,9 @@ BasicTerminalBuffer::MakeLinesSnapshots(time_t timeStamp, const char* fileName) fprintf(fileOut, "%02" B_PRId16 ":%02" B_PRId16 ":%08" B_PRIx32 ":\n", i, line->length, line->attributes); for (int j = 0; j < line->length; j++) - fprintf(fileOut, "%c", line->cells[j].character.bytes[0]); + if (line->cells[j].character.bytes[0] != 0) + fwrite(line->cells[j].character.bytes, 1, + line->cells[j].character.ByteCount(), fileOut); fprintf(fileOut, "\n"); for (int s = 28; s >= 0; s -= 4) { @@ -1762,7 +1768,8 @@ BasicTerminalBuffer::StartStopDebugCapture() struct tm* ts = gmtime(&timeStamp); str << ts->tm_hour << ts->tm_min << ts->tm_sec; str << ".Capture.log"; - fCaptureFile = open(str.String(), O_CREAT | O_WRONLY); + fCaptureFile = open(str.String(), O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); } diff --git a/src/apps/terminal/BasicTerminalBuffer.h b/src/apps/terminal/BasicTerminalBuffer.h index 2dca366872..ed30bb09f2 100644 --- a/src/apps/terminal/BasicTerminalBuffer.h +++ b/src/apps/terminal/BasicTerminalBuffer.h @@ -122,13 +122,8 @@ public: void CaptureChar(char ch); // insert chars/lines - inline void InsertChar(UTF8Char c); - void InsertChar(UTF8Char c, uint32 width); - inline void InsertChar(const char* c); - inline void InsertChar(const char* c, int32 length); - inline void InsertChar(const char* c, int32 length, - uint32 width); - void FillScreen(UTF8Char c, uint32 width, uint32 attr); + void InsertChar(UTF8Char c); + void FillScreen(UTF8Char c, uint32 attr); void InsertCR(); void InsertLF(); @@ -273,34 +268,6 @@ BasicTerminalBuffer::SetAttributes(uint32 attributes) } -void -BasicTerminalBuffer::InsertChar(UTF8Char c) -{ - return InsertChar(c, 1); -} - - -void -BasicTerminalBuffer::InsertChar(const char* c) -{ - return InsertChar(UTF8Char(c), 1); -} - - -void -BasicTerminalBuffer::InsertChar(const char* c, int32 length) -{ - return InsertChar(UTF8Char(c, length), 1); -} - - -void -BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 width) -{ - return InsertChar(UTF8Char(c, length), width); -} - - void BasicTerminalBuffer::EraseChars(int32 numChars) { diff --git a/src/apps/terminal/HistoryBuffer.cpp b/src/apps/terminal/HistoryBuffer.cpp index 3202c5a0af..ada86f5deb 100644 --- a/src/apps/terminal/HistoryBuffer.cpp +++ b/src/apps/terminal/HistoryBuffer.cpp @@ -121,7 +121,9 @@ HistoryBuffer::GetTerminalLineAt(int32 index, TerminalLine* buffer) const // full width char? if (cell.character.IsFullWidth()) { cell.attributes |= A_WIDTH; - charCount++; + // attributes of the second, "invisible" cell must be + // cleared to let full-width chars detection work properly + buffer->cells[charCount++].attributes = 0; } } diff --git a/src/apps/terminal/SetTitleDialog.cpp b/src/apps/terminal/SetTitleDialog.cpp index 72deef82c0..563f518f27 100644 --- a/src/apps/terminal/SetTitleDialog.cpp +++ b/src/apps/terminal/SetTitleDialog.cpp @@ -32,6 +32,7 @@ SetTitleDialog::SetTitleDialog(const char* dialogTitle, const char* label, B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), fListener(NULL), fTitle(), + fOldTitleUserDefined(false), fTitleUserDefined(false) { BLayoutBuilder::Group<>(this, B_VERTICAL) diff --git a/src/apps/terminal/Shell.cpp b/src/apps/terminal/Shell.cpp index 11793568ba..b6c70ff8ad 100644 --- a/src/apps/terminal/Shell.cpp +++ b/src/apps/terminal/Shell.cpp @@ -74,7 +74,7 @@ // TODO: should extract from /etc/passwd instead??? const char *kDefaultShell = "/bin/sh"; -const char *kTerminalType = "xterm-256color"; +const char *kTerminalType = "xterm"; /* * Set environment variable. diff --git a/src/apps/terminal/TermConst.h b/src/apps/terminal/TermConst.h index 0471b1cc8e..942d9215d8 100644 --- a/src/apps/terminal/TermConst.h +++ b/src/apps/terminal/TermConst.h @@ -159,8 +159,10 @@ enum { static const int32 DEFAULT = -1; // Font Width -static const int HALF_WIDTH = 1; -static const int FULL_WIDTH = 2; +enum { + HALF_WIDTH = 1, + FULL_WIDTH = 2 +}; #define M_UTF8 -1 diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index ece385aa1e..c2b1edacd9 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -37,7 +37,6 @@ extern int gUTF8GroundTable[]; /* UTF8 Ground table */ -extern int gCS96GroundTable[]; /* CS96 Ground table */ extern int gISO8859GroundTable[]; /* ISO8859 & EUC Ground table */ extern int gWinCPGroundTable[]; /* Windows cp1252, cp1251, koi-8r */ extern int gSJISGroundTable[]; /* Shift-JIS Ground table */ @@ -49,7 +48,6 @@ extern int gScrTable[]; /* ESC # */ extern int gIgnoreTable[]; /* ignore table */ extern int gIesTable[]; /* ignore ESC table */ extern int gEscIgnoreTable[]; /* ESC ignore table */ -extern int gMbcsTable[]; /* ESC $ */ extern const char* gLineDrawGraphSet[]; /* may be used for G0, G1, G2, G3 */ @@ -290,7 +288,6 @@ TermParse::DumpState(int *groundtable, int *parsestate, uchar c) #define T(t) \ { t, #t } T(gUTF8GroundTable), - T(gCS96GroundTable), T(gISO8859GroundTable), T(gWinCPGroundTable), T(gSJISGroundTable), @@ -301,7 +298,6 @@ TermParse::DumpState(int *groundtable, int *parsestate, uchar c) T(gIgnoreTable), T(gIesTable), T(gEscIgnoreTable), - T(gMbcsTable), { NULL, NULL } }; int i; @@ -339,7 +335,6 @@ TermParse::_GuessGroundTable(int encoding) case B_EUC_CONVERSION: case B_EUC_KR_CONVERSION: case B_JIS_CONVERSION: - case B_GBK_CONVERSION: case B_BIG5_CONVERSION: return gISO8859GroundTable; @@ -348,6 +343,7 @@ TermParse::_GuessGroundTable(int encoding) case B_MS_WINDOWS_CONVERSION: case B_MAC_ROMAN_CONVERSION: case B_MS_DOS_866_CONVERSION: + case B_GBK_CONVERSION: case B_MS_DOS_CONVERSION: return gWinCPGroundTable; @@ -368,12 +364,9 @@ TermParse::EscParse() { int top; int bottom; -// int cs96 = 0; - uchar curess = 0; char cbuf[4] = { 0 }; char dstbuf[4] = { 0 }; - char *ptr; int currentEncoding = -1; @@ -392,11 +385,6 @@ TermParse::EscParse() int curGL = 0; int curGR = 0; - int32 srcLen = sizeof(cbuf); - int32 dstLen = sizeof(dstbuf); - int32 dummyState = 0; - - int width = 1; BAutolock locker(fBuffer); while (!fQuitting) { @@ -413,6 +401,9 @@ TermParse::EscParse() } //debug_printf("TermParse: char: '%c' (%d), parse state: %d\n", c, c, parsestate[c]); + int32 srcLen = 0; + int32 dstLen = sizeof(dstbuf); + int32 dummyState = 0; switch (parsestate[c]) { case CASE_PRINT: @@ -431,70 +422,48 @@ TermParse::EscParse() break; } case CASE_PRINT_GR: + { /* case iso8859 gr character, or euc */ - ptr = cbuf; - if (currentEncoding == B_EUC_CONVERSION - || currentEncoding == B_EUC_KR_CONVERSION - || currentEncoding == B_JIS_CONVERSION - || currentEncoding == B_GBK_CONVERSION - || currentEncoding == B_BIG5_CONVERSION) { - switch (parsestate[curess]) { - case CASE_SS2: /* JIS X 0201 */ - width = 1; - *ptr++ = curess; - *ptr++ = c; - *ptr = 0; - curess = 0; - break; + switch (currentEncoding) { + case B_EUC_CONVERSION: + case B_EUC_KR_CONVERSION: + case B_JIS_CONVERSION: + case B_BIG5_CONVERSION: + cbuf[srcLen++] = c; + c = _NextParseChar(); + cbuf[srcLen++] = c; + break; - case CASE_SS3: /* JIS X 0212 */ - width = 1; - *ptr++ = curess; - *ptr++ = c; + case B_GBK_CONVERSION: + cbuf[srcLen++] = c; + do { + // GBK-compatible codepoints are 2-bytes long c = _NextParseChar(); - *ptr++ = c; - *ptr = 0; - curess = 0; - break; + cbuf[srcLen++] = c; - default: /* JIS X 0208 */ - width = 2; - *ptr++ = c; - c = _NextParseChar(); - *ptr++ = c; - *ptr = 0; - break; - } - } else { - /* ISO-8859-1...10 and MacRoman */ - *ptr++ = c; - *ptr = 0; + // GB18030 extends GBK with 4-byte codepoints + // using 2nd byte from range 0x30...0x39 + if (srcLen == 2 && (c < 0x30 || c > 0x39)) + break; + } while (srcLen < 4); + break; + + default: // ISO-8859-1...10 and MacRoman + cbuf[srcLen++] = c; + break; } - srcLen = strlen(cbuf); - dstLen = sizeof(dstbuf); - if (currentEncoding != B_JIS_CONVERSION) { - convert_to_utf8(currentEncoding, cbuf, &srcLen, - dstbuf, &dstLen, &dummyState, '?'); - } else { - convert_to_utf8(B_EUC_CONVERSION, cbuf, &srcLen, + if (srcLen > 0) { + int encoding = currentEncoding == B_JIS_CONVERSION + ? B_EUC_CONVERSION : currentEncoding; + + convert_to_utf8(encoding, cbuf, &srcLen, dstbuf, &dstLen, &dummyState, '?'); + + fBuffer->InsertChar(UTF8Char(dstbuf, dstLen)); } - - fBuffer->InsertChar(dstbuf, dstLen, width); - break; - - case CASE_PRINT_CS96: - cbuf[0] = c | 0x80; - c = _NextParseChar(); - cbuf[1] = c | 0x80; - cbuf[2] = 0; - srcLen = 2; - dstLen = sizeof(dstbuf); - convert_to_utf8(B_EUC_CONVERSION, cbuf, &srcLen, - dstbuf, &dstLen, &dummyState, '?'); - fBuffer->InsertChar(dstbuf, dstLen); break; + } case CASE_LF: fBuffer->InsertLF(); @@ -505,62 +474,47 @@ TermParse::EscParse() break; case CASE_SJIS_KANA: - cbuf[0] = c; - cbuf[1] = '\0'; - srcLen = 1; - dstLen = sizeof(dstbuf); + cbuf[srcLen++] = c; convert_to_utf8(currentEncoding, cbuf, &srcLen, dstbuf, &dstLen, &dummyState, '?'); - fBuffer->InsertChar(dstbuf, dstLen); + fBuffer->InsertChar(UTF8Char(dstbuf, dstLen)); break; case CASE_SJIS_INSTRING: - cbuf[0] = c; + cbuf[srcLen++] = c; c = _NextParseChar(); - cbuf[1] = c; - cbuf[2] = '\0'; - srcLen = 2; - dstLen = sizeof(dstbuf); + cbuf[srcLen++] = c; + convert_to_utf8(currentEncoding, cbuf, &srcLen, dstbuf, &dstLen, &dummyState, '?'); - fBuffer->InsertChar(dstbuf, dstLen); + fBuffer->InsertChar(UTF8Char(dstbuf, dstLen)); break; case CASE_UTF8_2BYTE: - cbuf[0] = c; + cbuf[srcLen++] = c; c = _NextParseChar(); if (groundtable[c] != CASE_UTF8_INSTRING) break; - cbuf[1] = c; - cbuf[2] = '\0'; + cbuf[srcLen++] = c; - fBuffer->InsertChar(cbuf, 2); + fBuffer->InsertChar(UTF8Char(cbuf, srcLen)); break; case CASE_UTF8_3BYTE: - cbuf[0] = c; - c = _NextParseChar(); - if (groundtable[c] != CASE_UTF8_INSTRING) - break; - cbuf[1] = c; + cbuf[srcLen++] = c; - c = _NextParseChar(); - if (groundtable[c] != CASE_UTF8_INSTRING) - break; - cbuf[2] = c; - cbuf[3] = '\0'; - fBuffer->InsertChar(cbuf, 3); - break; + do { + c = _NextParseChar(); + if (groundtable[c] != CASE_UTF8_INSTRING) { + srcLen = 0; + break; + } + cbuf[srcLen++] = c; - case CASE_MBCS: - /* ESC $ */ - parsestate = gMbcsTable; - break; + } while (srcLen != 3); - case CASE_GSETS: - /* ESC $ ? */ - parsestate = gCS96GroundTable; - // cs96 = 1; + if (srcLen > 0) + fBuffer->InsertChar(UTF8Char(cbuf, srcLen)); break; case CASE_SCS_STATE: @@ -1029,7 +983,7 @@ TermParse::EscParse() case CASE_DECALN: /* DECALN */ - fBuffer->FillScreen(UTF8Char('E'), 1, 0); + fBuffer->FillScreen(UTF8Char('E'), 0); parsestate = groundtable; break; @@ -1073,13 +1027,11 @@ TermParse::EscParse() case CASE_SS2: /* SS2 */ - curess = c; parsestate = groundtable; break; case CASE_SS3: /* SS3 */ - curess = c; parsestate = groundtable; break; diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index 17d2d428c7..89faf10feb 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -498,8 +498,9 @@ TermView::_ConvertFromTerminal(const TermPos &pos) inline void TermView::_InvalidateTextRect(int32 x1, int32 y1, int32 x2, int32 y2) { + // assume the worst case with full-width characters - invalidate 2 cells BRect rect(x1 * fFontWidth, _LineOffset(y1), - (x2 + 1) * fFontWidth - 1, _LineOffset(y2 + 1) - 1); + (x2 + 1) * fFontWidth * 2 - 1, _LineOffset(y2 + 1) - 1); //debug_printf("Invalidate((%f, %f) - (%f, %f))\n", rect.left, rect.top, //rect.right, rect.bottom); Invalidate(rect); @@ -1030,12 +1031,8 @@ TermView::_DrawCursor() if (fVisibleTextBuffer->GetChar(fCursor.y - firstVisible, fCursor.x, character, attr) == A_CHAR && (fCursorStyle == BLOCK_CURSOR || !cursorVisible)) { - int32 width; - if (IS_WIDTH(attr)) - width = 2; - else - width = 1; + int32 width = IS_WIDTH(attr) ? FULL_WIDTH : HALF_WIDTH; char buffer[5]; int32 bytes = UTF8Char::ByteCount(character.bytes[0]); memcpy(buffer, character.bytes, bytes); @@ -1064,6 +1061,9 @@ TermView::_DrawCursor() SetHighColor(rgb_back); } + if (IS_WIDTH(attr) && fCursorStyle != IBEAM_CURSOR) + rect.right += fFontWidth; + FillRect(rect); } } @@ -1287,8 +1287,13 @@ TermView::Draw(BRect updateRect) continue; } + // Note: full-width characters GetString()-ed always + // with count 1, so this hardcoding is safe. From the other + // side - drawing the whole string with one call render the + // characters not aligned to cells grid - that looks much more + // inaccurate for full-width strings than for half-width ones. if (IS_WIDTH(attr)) - count = 2; + count = FULL_WIDTH; _DrawLinePart(fFontWidth * i, (int32)_LineOffset(j), attr, buf, count, insideSelection, false, this); diff --git a/src/apps/terminal/UTF8Char.h b/src/apps/terminal/UTF8Char.h index a981c003de..ffac26da80 100644 --- a/src/apps/terminal/UTF8Char.h +++ b/src/apps/terminal/UTF8Char.h @@ -16,6 +16,7 @@ struct UTF8Char { UTF8Char() { + bytes[0] = 0; } UTF8Char(char c) @@ -64,7 +65,13 @@ struct UTF8Char { bool IsFullWidth() const { - // TODO: Implement! + switch (BUnicodeChar::EastAsianWidth(BUnicodeChar::FromUTF8(bytes))) { + case B_UNICODE_EA_FULLWIDTH: + case B_UNICODE_EA_WIDE: + return true; + default: + break; + } return false; } diff --git a/src/apps/terminal/VTPrsTbl.c b/src/apps/terminal/VTPrsTbl.c index 8e464107a4..db8d479611 100644 --- a/src/apps/terminal/VTPrsTbl.c +++ b/src/apps/terminal/VTPrsTbl.c @@ -14,8 +14,6 @@ #include "VTparse.h" -#define USE_MBCS -#define USE_ISO2022 // #pragma mark UTF8 coding ground table int gUTF8GroundTable[] = @@ -342,331 +340,6 @@ CASE_UTF8_3BYTE, CASE_UTF8_3BYTE, }; -// #pragma mark charset 96 table -int gCS96GroundTable[] = -{ -/* NUL SOH STX ETX */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* EOT ENQ ACK BEL */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_BELL, -/* BS HT NL VT */ -CASE_BS, -CASE_TAB, -CASE_LF, -CASE_LF, /* CASE_UP*/ -/* NP CR SO SI */ -CASE_LF, /* CASE_IGNORE*/ -CASE_CR, -CASE_LS1, -CASE_LS0, -/* DLE DC1 DC2 DC3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* DC4 NAK SYN ETB */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* CAN EM SUB ESC */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_ESC, -/* FS GS RS US */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* SP ! " # */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* $ % & ' */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* ( ) * + */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* , - . / */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* 0 1 2 3 */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* 4 5 6 7 */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* 8 9 : ; */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* < = > ? */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* @ A B C */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* D E F G */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* H I J K */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* L M N O */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* P Q R S */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* T U V W */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* X Y Z [ */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* \ ] ^ _ */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* ` a b c */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* d e f g */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* h i j k */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* l m n o */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* p q r s */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* t u v w */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* x y z { */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* | } ~ DEL */ -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -CASE_PRINT_CS96, -/* 0x80 0x81 0x82 0x83 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x84 0x85 0x86 0x87 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x88 0x89 0x8a 0x8b */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x8c 0x8d 0x8e 0x8f */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x90 0x91 0x92 0x93 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x94 0x95 0x96 0x97 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x99 0x99 0x9a 0x9b */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x9c 0x9d 0x9e 0x9f */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xa0 0xa1 0xa2 0xa3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xa4 0xa5 0xa6 0xa7 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xa8 0xa9 0xaa 0xab */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xac 0xad 0xae 0xaf */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xb0 0xb1 0xb2 0xb3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xb4 0xb5 0xb6 0xb7 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xb8 0xb9 0xba 0xbb */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xbc 0xbd 0xbe 0xbf */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xc0 0xc1 0xc2 0xc3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xc4 0xc5 0xc6 0xc7 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xc8 0xc9 0xca 0xcb */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xcc 0xcd 0xce 0xcf */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xd0 0xd1 0xd2 0xd3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xd4 0xd5 0xd6 0xd7 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xd8 0xd9 0xda 0xdb */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xdc 0xdd 0xde 0xdf */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xe0 0xe1 0xe2 0xe3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xe4 0xe5 0xe6 0xe7 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xe8 0xe9 0xea 0xeb */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xec 0xed 0xee 0xef */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xf0 0xf1 0xf2 0xf3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xf4 0xf5 0xf6 0xf7 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xf8 0xf9 0xfa 0xfb */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0xfc 0xfd 0xfe 0xff */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -}; - // #pragma mark ISO8859 table int gISO8859GroundTable[] = { @@ -749,7 +422,7 @@ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, -CASE_PRINT, +CASE_PRINT, /* @ A B C */ CASE_PRINT, CASE_PRINT, @@ -992,7 +665,10 @@ CASE_PRINT_GR, CASE_PRINT_GR, }; -// #pragma mark WinCP table (Windows cp1252, cp1251, koi-8r etc.) +// #pragma mark WinCP table (ISO8859 + C1) +// This one defines both C1 control and GR characters +// as CASE_PRINT_GR to let process set of encodings +// using this areas: cp1252, cp1251, koi-8r, cp866, gb18030 int gWinCPGroundTable[] = { /* NUL SOH STX ETX */ @@ -1154,7 +830,7 @@ CASE_PRINT, CASE_PRINT, CASE_PRINT, CASE_PRINT, -CASE_PRINT, //TODO??? +CASE_PRINT, /* 0x80 0x81 0x82 0x83 */ CASE_PRINT_GR, CASE_PRINT_GR, @@ -1732,20 +1408,11 @@ CASE_GROUND_STATE, CASE_GROUND_STATE, /* D E F G */ CASE_GROUND_STATE, -#ifdef STATUSLINE -CASE_ERASE_STATUS, -CASE_FROM_STATUS, -#else /* !STATUSLINE */ CASE_GROUND_STATE, CASE_GROUND_STATE, -#endif /* !STATUSLINE */ CASE_GROUND_STATE, /* H I J K */ -#ifdef STATUSLINE -CASE_HIDE_STATUS, -#else /* !STATUSLINE */ CASE_GROUND_STATE, -#endif /* !STATUSLINE */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, @@ -1758,17 +1425,9 @@ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, -#ifdef STATUSLINE -CASE_SHOW_STATUS, -#else /* !STATUSLINE */ CASE_GROUND_STATE, -#endif /* !STATUSLINE */ /* T U V W */ -#ifdef STATUSLINE -CASE_TO_STATUS, -#else /* !STATUSLINE */ CASE_GROUND_STATE, -#endif /* !STATUSLINE */ CASE_GROUND_STATE, CASE_GROUND_STATE, CASE_GROUND_STATE, @@ -2359,38 +2018,20 @@ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_SCR_STATE, /* $ % & ' */ -#ifdef USE_ISO2022 -CASE_MBCS, -#else /* !USE_ISO2022 */ CASE_ESC_IGNORE, -#endif /* !USE_ISO2022 */ CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, /* ( ) * + */ -#ifdef USE_ISO2022 CASE_SCS_STATE, CASE_SCS_STATE, CASE_SCS_STATE, CASE_SCS_STATE, -#else /* !USE_ISO2022 */ -CASE_SCS0_STATE, -CASE_SCS1_STATE, -CASE_SCS2_STATE, -CASE_SCS3_STATE, -#endif /* !USE_ISO2022 */ /* , - . / */ -#ifdef USE_ISO2022 CASE_SCS_STATE, /* not defined in ISO2022 but used in Mule */ CASE_SCS_STATE, CASE_SCS_STATE, CASE_SCS_STATE, -#else /* !USE_ISO2022 */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -#endif /* !USE_ISO2022 */ /* 0 1 2 3 */ CASE_GROUND_STATE, CASE_GROUND_STATE, @@ -3628,1085 +3269,6 @@ CASE_GROUND_STATE, CASE_GROUND_STATE, }; -// #pragma mark ESC ( - SCS table -int gScsTable[] = -{ -/* NUL SOH STX ETX */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* EOT ENQ ACK BEL */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_BELL, -/* BS HT NL VT */ -CASE_BS, -CASE_TAB, -CASE_VMOT, -CASE_VMOT, -/* NP CR SO SI */ -CASE_VMOT, -CASE_CR, -CASE_LS1, -CASE_LS0, -/* DLE DC1 DC2 DC3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* DC4 NAK SYN ETB */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* CAN EM SUB ESC */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_ESC, -/* FS GS RS US */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* SP ! " # */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* $ % & ' */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* ( ) * + */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* , - . / */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -#ifdef USE_ISO2022 -/* 0 1 2 3 */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* 4 5 6 7 */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* 8 9 : ; */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* < = > ? */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* @ A B C */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* D E F G */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* H I J K */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* L M N O */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* P Q R S */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* T U V W */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* X Y Z [ */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* \ ] ^ _ */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* ` a b c */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* d e f g */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* h i j k */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* l m n o */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GROUND_STATE, /* GSET('p') >= 0x40 (MBCS flag) */ -/* p q r s */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* t u v w */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* x y z { */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* | } ~ DEL */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, /* empty character set */ -CASE_GROUND_STATE, -#else /* !USE_ISO2022 */ -/* 0 1 2 3 */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GROUND_STATE, -/* 4 5 6 7 */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* 8 9 : ; */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* < = > ? */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* @ A B C */ -CASE_GROUND_STATE, -CASE_GSETS, -CASE_GSETS, -CASE_GROUND_STATE, -/* D E F G */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* H I J K */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* L M N O */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* P Q R S */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* T U V W */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* X Y Z [ */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* \ ] ^ _ */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* ` a b c */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* d e f g */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* h i j k */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* l m n o */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* p q r s */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* t u v w */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* x y z { */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* | } ~ DEL */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -#endif /* !USE_ISO2022 */ -/* 0x80 0x81 0x82 0x83 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x84 0x85 0x86 0x87 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x88 0x89 0x8a 0x8b */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x8c 0x8d 0x8e 0x8f */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x90 0x91 0x92 0x93 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x94 0x95 0x96 0x97 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x99 0x99 0x9a 0x9b */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x9c 0x9d 0x9e 0x9f */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* nobreakspace exclamdown cent sterling */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* currency yen brokenbar section */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* diaeresis copyright ordfeminine guillemotleft */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* notsign hyphen registered macron */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* degree plusminus twosuperior threesuperior */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* acute mu paragraph periodcentered */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* cedilla onesuperior masculine guillemotright */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* onequarter onehalf threequarters questiondown */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Agrave Aacute Acircumflex Atilde */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Adiaeresis Aring AE Ccedilla */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Egrave Eacute Ecircumflex Ediaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Igrave Iacute Icircumflex Idiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Eth Ntilde Ograve Oacute */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Ocircumflex Otilde Odiaeresis multiply */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Ooblique Ugrave Uacute Ucircumflex */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Udiaeresis Yacute Thorn ssharp */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* agrave aacute acircumflex atilde */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* adiaeresis aring ae ccedilla */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* egrave eacute ecircumflex ediaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* igrave iacute icircumflex idiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* eth ntilde ograve oacute */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* ocircumflex otilde odiaeresis division */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* oslash ugrave uacute ucircumflex */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* udiaeresis yacute thorn ydiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -}; - -#ifdef USE_MBCS -// #pragma mark MBCS table -int gMbcsTable[] = { -/* NUL SOH STX ETX */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* EOT ENQ ACK BEL */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_BELL, -/* BS HT NL VT */ -CASE_BS, -CASE_TAB, -CASE_VMOT, -CASE_VMOT, -/* NP CR SO SI */ -CASE_VMOT, -CASE_CR, -CASE_LS1, -CASE_LS0, -/* DLE DC1 DC2 DC3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* DC4 NAK SYN ETB */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* CAN EM SUB ESC */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_ESC, -/* FS GS RS US */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* SP ! " # */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* $ % & ' */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* ( ) * + */ -CASE_IGNORE, /*CASE_SCS_STATE,*/ -CASE_SCS_STATE, -CASE_SCS_STATE, -CASE_SCS_STATE, -/* , - . / */ -CASE_ESC_IGNORE, -CASE_SCS_STATE, -CASE_SCS_STATE, -CASE_SCS_STATE, -/* 0 1 2 3 */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* 4 5 6 7 */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* 8 9 : ; */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* < = > ? */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* @ A B C */ -CASE_GSETS, /* ESC-$-@ (JIS-78) */ -CASE_GSETS, /* ESC-$-A (GB) */ -CASE_GSETS, /* ESC-$-B (JIS-83) */ -CASE_GROUND_STATE, -/* D E F G */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* H I J K */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* L M N O */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* P Q R S */ -CASE_IGNORE_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* T U V W */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* X Y Z [ */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* \ ] ^ _ */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_IGNORE_STATE, -CASE_IGNORE_STATE, -/* ` a b c */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* d e f g */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* h i j k */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* l m n o */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* p q r s */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* t u v w */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* x y z { */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* | } ~ DEL */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* 0x80 0x81 0x82 0x83 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x84 0x85 0x86 0x87 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x88 0x89 0x8a 0x8b */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x8c 0x8d 0x8e 0x8f */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x90 0x91 0x92 0x93 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x94 0x95 0x96 0x97 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x99 0x99 0x9a 0x9b */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x9c 0x9d 0x9e 0x9f */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* nobreakspace exclamdown cent sterling */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* currency yen brokenbar section */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* diaeresis copyright ordfeminine guillemotleft */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* notsign hyphen registered macron */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* degree plusminus twosuperior threesuperior */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* acute mu paragraph periodcentered */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* cedilla onesuperior masculine guillemotright */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* onequarter onehalf threequarters questiondown */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Agrave Aacute Acircumflex Atilde */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Adiaeresis Aring AE Ccedilla */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Egrave Eacute Ecircumflex Ediaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Igrave Iacute Icircumflex Idiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Eth Ntilde Ograve Oacute */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Ocircumflex Otilde Odiaeresis multiply */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Ooblique Ugrave Uacute Ucircumflex */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Udiaeresis Yacute Thorn ssharp */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* agrave aacute acircumflex atilde */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* adiaeresis aring ae ccedilla */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* egrave eacute ecircumflex ediaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* igrave iacute icircumflex idiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* eth ntilde ograve oacute */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* ocircumflex otilde odiaeresis division */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* oslash ugrave uacute ucircumflex */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* udiaeresis yacute thorn ydiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -}; - -// #pragma mark SMBCS table -int gSmbcsTable[] = { -/* NUL SOH STX ETX */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* EOT ENQ ACK BEL */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_BELL, -/* BS HT NL VT */ -CASE_BS, -CASE_TAB, -CASE_VMOT, -CASE_VMOT, -/* NP CR SO SI */ -CASE_VMOT, -CASE_CR, -CASE_LS1, -CASE_LS0, -/* DLE DC1 DC2 DC3 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* DC4 NAK SYN ETB */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* CAN EM SUB ESC */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_ESC, -/* FS GS RS US */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* SP ! " # */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* $ % & ' */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* ( ) * + */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* , - . / */ -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -CASE_ESC_IGNORE, -/* 0 1 2 3 */ -CASE_GROUND_STATE, /* (2-byte or more) private character set */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* 4 5 6 7 */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* 8 9 : ; */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* < = > ? */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* @ A B C */ -CASE_GSETS, /* ESC-$-I-F */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* D E F G */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* H I J K */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* L M N O */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* P Q R S */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* T U V W */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* X Y Z [ */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* \ ] ^ _ */ -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -CASE_GSETS, -/* ` a b c */ -CASE_GROUND_STATE, /* 3-byte character set */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* d e f g */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* h i j k */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* l m n o */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* p q r s */ -CASE_GROUND_STATE, /* 4-byte character set */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* t u v w */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* x y z { */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* | } ~ DEL */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* 0x80 0x81 0x82 0x83 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x84 0x85 0x86 0x87 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x88 0x89 0x8a 0x8b */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x8c 0x8d 0x8e 0x8f */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x90 0x91 0x92 0x93 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x94 0x95 0x96 0x97 */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x99 0x99 0x9a 0x9b */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* 0x9c 0x9d 0x9e 0x9f */ -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -CASE_IGNORE, -/* nobreakspace exclamdown cent sterling */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* currency yen brokenbar section */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* diaeresis copyright ordfeminine guillemotleft */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* notsign hyphen registered macron */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* degree plusminus twosuperior threesuperior */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* acute mu paragraph periodcentered */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* cedilla onesuperior masculine guillemotright */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* onequarter onehalf threequarters questiondown */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Agrave Aacute Acircumflex Atilde */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Adiaeresis Aring AE Ccedilla */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Egrave Eacute Ecircumflex Ediaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Igrave Iacute Icircumflex Idiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Eth Ntilde Ograve Oacute */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Ocircumflex Otilde Odiaeresis multiply */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Ooblique Ugrave Uacute Ucircumflex */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* Udiaeresis Yacute Thorn ssharp */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* agrave aacute acircumflex atilde */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* adiaeresis aring ae ccedilla */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* egrave eacute ecircumflex ediaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* igrave iacute icircumflex idiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* eth ntilde ograve oacute */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* ocircumflex otilde odiaeresis division */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* oslash ugrave uacute ucircumflex */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -/* udiaeresis yacute thorn ydiaeresis */ -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -CASE_GROUND_STATE, -}; - -#endif - // #pragma mark Shift-JIS ground table int gSJISGroundTable[] = { diff --git a/src/apps/terminal/VTparse.h b/src/apps/terminal/VTparse.h index da48dd124f..58d9e8f873 100644 --- a/src/apps/terminal/VTparse.h +++ b/src/apps/terminal/VTparse.h @@ -25,10 +25,6 @@ #define CASE_LS1 12 #define CASE_SP 13 #define CASE_SCR_STATE 14 -#define CASE_SCS0_STATE 15 -#define CASE_SCS1_STATE 16 -#define CASE_SCS2_STATE 17 -#define CASE_SCS3_STATE 18 #define CASE_ESC_IGNORE 19 #define CASE_ESC_DIGIT 20 #define CASE_ESC_SEMI 21 @@ -56,7 +52,6 @@ #define CASE_DECSET 43 #define CASE_DECRST 44 #define CASE_DECALN 45 -#define CASE_GSETS 46 #define CASE_DECSC 47 #define CASE_DECRC 48 #define CASE_DECKPAM 49 @@ -83,12 +78,6 @@ #define CASE_HP_MEM_LOCK 70 #define CASE_HP_MEM_UNLOCK 71 #define CASE_HP_BUGGY_LL 72 -#define CASE_TO_STATUS 73 -#define CASE_FROM_STATUS 74 -#define CASE_SHOW_STATUS 75 -#define CASE_HIDE_STATUS 76 -#define CASE_ERASE_STATUS 77 -#define CASE_MBCS 78 #define CASE_SCS_STATE 79 #define CASE_UTF8_2BYTE 80 #define CASE_UTF8_3BYTE 81 @@ -96,7 +85,6 @@ #define CASE_SJIS_INSTRING 83 #define CASE_SJIS_KANA 84 #define CASE_PRINT_GR 85 -#define CASE_PRINT_CS96 86 // additions, maybe reorder/reuse older ones ? #define CASE_VPA 87 #define CASE_HPA 88 diff --git a/src/bin/WindowShade.cpp b/src/bin/WindowShade.cpp index 7f2f480b27..1d2beface0 100644 --- a/src/bin/WindowShade.cpp +++ b/src/bin/WindowShade.cpp @@ -57,6 +57,7 @@ static struct option const kLongOptions[] = { I(list_selected_background_color, B_LIST_SELECTED_BACKGROUND_COLOR), I(list_item_text_color, B_LIST_ITEM_TEXT_COLOR), I(list_selected_item_text_color, B_LIST_SELECTED_ITEM_TEXT_COLOR), + I(scroll_bar_thumb_color, B_SCROLL_BAR_THUMB_COLOR), I(tooltip_background_color, B_TOOL_TIP_BACKGROUND_COLOR), I(tooltip_text_color, B_TOOL_TIP_TEXT_COLOR), I(success_color, B_SUCCESS_COLOR), diff --git a/src/bin/bash/builtins/common.c b/src/bin/bash/builtins/common.c index 6ba641b802..2c75b8419b 100644 --- a/src/bin/bash/builtins/common.c +++ b/src/bin/bash/builtins/common.c @@ -760,7 +760,7 @@ display_signal_list (list, forcecols) list = list->next; continue; } -#if defined (JOB_CONTROL) +#if defined (JOB_CONTROL) && defined(HAVE_KILL_BUILTIN) /* 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,8 +771,10 @@ 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) { diff --git a/src/bin/bash/builtins/kill.def b/src/bin/bash/builtins/kill.def index 734da250e2..4cff928360 100644 --- a/src/bin/bash/builtins/kill.def +++ b/src/bin/bash/builtins/kill.def @@ -22,6 +22,7 @@ $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. diff --git a/src/bin/coreutils/src/kill.c b/src/bin/coreutils/src/kill.c index dab4fa834e..f65b0cad12 100644 --- a/src/bin/coreutils/src/kill.c +++ b/src/bin/coreutils/src/kill.c @@ -21,6 +21,7 @@ #include #include #include +#include #if HAVE_SYS_WAIT_H # include @@ -36,6 +37,7 @@ #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" @@ -85,7 +87,7 @@ usage (int status) else { printf (_("\ -Usage: %s [-s SIGNAL | -SIGNAL] PID...\n\ +Usage: %s [-s SIGNAL | -SIGNAL] ...\n\ or: %s -l [SIGNAL]...\n\ or: %s -t [SIGNAL]...\n\ "), @@ -109,6 +111,8 @@ 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 (); @@ -196,38 +200,115 @@ 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; + int status = EXIT_SUCCESS; + char const *arg = *argv; + pid_t pid; - do - { - char *endp; - intmax_t n = (errno = 0, strtoimax (arg, &endp, 10)); - pid_t pid = n; + 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; - 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)); + } while ((arg = *++argv)); - return status; + return status; } - + + int main (int argc, char **argv) { diff --git a/src/bin/setmime.cpp b/src/bin/setmime.cpp index c69f6fa747..763c2680ab 100644 --- a/src/bin/setmime.cpp +++ b/src/bin/setmime.cpp @@ -936,7 +936,7 @@ MimeType::_Dump(const char* mimetype) throw (Error) _DumpIcon((uint8*) fBigIcon->Bits(), fBigIcon->BitsLength()); } - if (fVectorIcon != NULL && fVectorIcon != NULL) { + if (fVectorIcon != NULL && fVectorIconSize != 0) { cout << " \\" << endl << "\t" << kVectorIcon << " "; _DumpIcon((uint8*) fVectorIcon, fVectorIconSize); } diff --git a/src/bin/sysinfo.cpp b/src/bin/sysinfo.cpp index 0723ff8ab5..bff7ec31a0 100644 --- a/src/bin/sysinfo.cpp +++ b/src/bin/sysinfo.cpp @@ -409,9 +409,10 @@ print_extended_features(uint32 features) { static const char *kFeatures[32] = { "SSE3", "PCLMULDQ", "DTES64", "MONITOR", "DS-CPL", "VMX", "SMX", "EST", - "TM2", "SSSE3", "CNTXT-ID", NULL, NULL, "CX16", "xTPR", "PDCM", - NULL, NULL, "DCA", "SSE4.1", "SSE4.2", "x2APIC", "MOVEB", "POPCNT", - NULL, "AES", "XSAVE", "OSXSAVE", NULL, NULL, NULL, NULL + "TM2", "SSSE3", "CNTXT-ID", NULL, "FMA", "CX16", "xTPR", "PDCM", + NULL, "PCID", "DCA", "SSE4.1", "SSE4.2", "x2APIC", "MOVEB", "POPCNT", + "TSC-DEADLINE", "AES", "XSAVE", "OSXSAVE", "AVX", "F16C", "RDRND", + "HYPERVISOR" }; int32 found = 0; diff --git a/src/kits/debug/Image.cpp b/src/kits/debug/Image.cpp index 1022792350..b2f23d3a3e 100644 --- a/src/kits/debug/Image.cpp +++ b/src/kits/debug/Image.cpp @@ -400,3 +400,65 @@ KernelImage::Init(const image_info& info) fSymbolTable, &fSymbolCount, fStringTable, &fStringTableSize, &fLoadDelta); } + + +CommPageImage::CommPageImage() +{ +} + + +CommPageImage::~CommPageImage() +{ + delete[] fSymbolTable; + delete[] fStringTable; +} + + +status_t +CommPageImage::Init(const image_info& info) +{ + // find kernel image for commpage + image_id commPageID = -1; + image_info commPageInfo; + + int32 cookie = 0; + while (_kern_get_next_image_info(B_SYSTEM_TEAM, &cookie, &commPageInfo, + sizeof(image_info)) == B_OK) { + if (!strcmp("commpage", commPageInfo.name)) { + commPageID = commPageInfo.id; + break; + } + } + if (commPageID < 0) + return B_ENTRY_NOT_FOUND; + + fInfo = commPageInfo; + fInfo.text = info.text; + + // get the table sizes + fSymbolCount = 0; + fStringTableSize = 0; + status_t error = _kern_read_kernel_image_symbols(commPageID, NULL, + &fSymbolCount, NULL, &fStringTableSize, NULL); + if (error != B_OK) + return error; + + // allocate the tables + fSymbolTable = new(std::nothrow) elf_sym[fSymbolCount]; + fStringTable = new(std::nothrow) char[fStringTableSize]; + if (fSymbolTable == NULL || fStringTable == NULL) + return B_NO_MEMORY; + + // get the info + error = _kern_read_kernel_image_symbols(commPageID, + fSymbolTable, &fSymbolCount, fStringTable, &fStringTableSize, NULL); + if (error != B_OK) { + delete[] fSymbolTable; + delete[] fStringTable; + return error; + } + + fLoadDelta = (addr_t)info.text; + + return B_OK; +} diff --git a/src/kits/debug/Image.h b/src/kits/debug/Image.h index aa4e76db89..4d4be64951 100644 --- a/src/kits/debug/Image.h +++ b/src/kits/debug/Image.h @@ -111,6 +111,15 @@ public: status_t Init(const image_info& info); }; + +class CommPageImage : public SymbolTableBasedImage { +public: + CommPageImage(); + virtual ~CommPageImage(); + + status_t Init(const image_info& info); +}; + } // namespace Debug } // namespace BPrivate diff --git a/src/kits/debug/SymbolLookup.cpp b/src/kits/debug/SymbolLookup.cpp index cb061064e6..2d259fb666 100644 --- a/src/kits/debug/SymbolLookup.cpp +++ b/src/kits/debug/SymbolLookup.cpp @@ -295,6 +295,14 @@ SymbolLookup::Init() error = kernelImage->Init(imageInfo); image = kernelImage; + } else if (!strcmp("commpage", imageInfo.name)) { + // commpage image + CommPageImage* commPageImage = new(std::nothrow) CommPageImage; + if (commPageImage == NULL) + return B_NO_MEMORY; + + error = commPageImage->Init(imageInfo); + image = commPageImage; } else { // userland image -- try to load an image file ImageFile* imageFile = new(std::nothrow) ImageFile; diff --git a/src/kits/interface/ControlLook.cpp b/src/kits/interface/ControlLook.cpp index 33bbe6231c..0be8af3338 100644 --- a/src/kits/interface/ControlLook.cpp +++ b/src/kits/interface/ControlLook.cpp @@ -762,6 +762,26 @@ BControlLook::DrawArrowShape(BView* view, BRect& rect, const BRect& updateRect, rect.top + 1 + rect.Height() / 1.33); tri3.Set(rect.right + 1, rect.top + 1); break; + case B_LEFT_UP_ARROW: + tri1.Set(rect.left, rect.bottom); + tri2.Set(rect.left, rect.top); + tri3.Set(rect.right - 1, rect.top); + break; + case B_RIGHT_UP_ARROW: + tri1.Set(rect.left + 1, rect.top); + tri2.Set(rect.right, rect.top); + tri3.Set(rect.right, rect.bottom); + break; + case B_RIGHT_DOWN_ARROW: + tri1.Set(rect.right, rect.top); + tri2.Set(rect.right, rect.bottom); + tri3.Set(rect.left + 1, rect.bottom); + break; + case B_LEFT_DOWN_ARROW: + tri1.Set(rect.right - 1, rect.bottom); + tri2.Set(rect.left, rect.bottom); + tri3.Set(rect.left, rect.top); + break; } BShape arrowShape; diff --git a/src/kits/interface/InterfaceDefs.cpp b/src/kits/interface/InterfaceDefs.cpp index 797a872413..b712b4f4b9 100644 --- a/src/kits/interface/InterfaceDefs.cpp +++ b/src/kits/interface/InterfaceDefs.cpp @@ -69,7 +69,7 @@ menu_info *_menu_info_ptr_; extern "C" const char B_NOTIFICATION_SENDER[] = "be:sender"; -static const rgb_color _kDefaultColors[kNumColors] = { +static const rgb_color _kDefaultColors[kColorWhichCount] = { {216, 216, 216, 255}, // B_PANEL_BACKGROUND_COLOR {216, 216, 216, 255}, // B_MENU_BACKGROUND_COLOR {255, 203, 0, 255}, // B_WINDOW_TAB_COLOR @@ -101,6 +101,7 @@ static const rgb_color _kDefaultColors[kNumColors] = { {153, 153, 153, 255}, // B_LIST_SELECTED_BACKGROUND_COLOR {0, 0, 0, 255}, // B_LIST_ITEM_TEXT_COLOR {0, 0, 0, 255}, // B_LIST_SELECTED_ITEM_TEXT_COLOR + {216, 216, 216, 255}, // B_SCROLL_BAR_THUMB_COLOR // 100... {0, 255, 0, 255}, // B_SUCCESS_COLOR {255, 0, 0, 255}, // B_FAILURE_COLOR @@ -1070,7 +1071,7 @@ rgb_color ui_color(color_which which) { int32 index = color_which_to_index(which); - if (index < 0 || index >= kNumColors) { + if (index < 0 || index >= kColorWhichCount) { fprintf(stderr, "ui_color(): unknown color_which %d\n", which); return make_color(0, 0, 0); } @@ -1089,7 +1090,7 @@ void set_ui_color(const color_which &which, const rgb_color &color) { int32 index = color_which_to_index(which); - if (index < 0 || index >= kNumColors) { + if (index < 0 || index >= kColorWhichCount) { fprintf(stderr, "set_ui_color(): unknown color_which %d\n", which); return; } @@ -1166,7 +1167,7 @@ _init_interface_kit_() return status; general_info.background_color = ui_color(B_PANEL_BACKGROUND_COLOR); - general_info.mark_color.set_to(0, 0, 0); + general_info.mark_color = ui_color(B_CONTROL_MARK_COLOR); general_info.highlight_color = ui_color(B_CONTROL_HIGHLIGHT_COLOR); general_info.window_frame_color = ui_color(B_WINDOW_TAB_COLOR); general_info.color_frame = true; diff --git a/src/kits/interface/ListView.cpp b/src/kits/interface/ListView.cpp index 31591b79fa..4cfe417675 100644 --- a/src/kits/interface/ListView.cpp +++ b/src/kits/interface/ListView.cpp @@ -1,13 +1,13 @@ /* - * Copyright 2001-2009, Haiku, Inc. All rights resrerved. + * Copyright 2001-2013 Haiku, Inc. All rights resrerved. * Distributed under the terms of the MIT license. * * Authors: - * Ulrich Wimboeck - * Marc Flerackers (mflerackers@androme.be) - * Stephan Assmus + * Stephan Assmus, superstippi@gmx.de * Axel Dörfler, axeld@pinc-software.de - * Rene Gollent (rene@gollent.com) + * Marc Flerackers, mflerackers@androme.be + * Rene Gollent, rene@gollent.com + * Ulrich Wimboeck */ @@ -33,16 +33,21 @@ struct track_data { bigtime_t last_click_time; }; + const float kDoubleClickTresh = 6; + static property_info sProperties[] = { { "Item", { B_COUNT_PROPERTIES, 0 }, { B_DIRECT_SPECIFIER, 0 }, - "Returns the number of BListItems currently in the list.", 0, { B_INT32_TYPE } + "Returns the number of BListItems currently in the list.", 0, + { B_INT32_TYPE } }, - { "Item", { B_EXECUTE_PROPERTY, 0 }, { B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, - B_RANGE_SPECIFIER, B_REVERSE_RANGE_SPECIFIER, 0 }, - "Select and invoke the specified items, first removing any existing selection." + { "Item", { B_EXECUTE_PROPERTY, 0 }, { B_INDEX_SPECIFIER, + B_REVERSE_INDEX_SPECIFIER, B_RANGE_SPECIFIER, + B_REVERSE_RANGE_SPECIFIER, 0 }, + "Select and invoke the specified items, first removing any existing " + "selection." }, { "Selection", { B_COUNT_PROPERTIES, 0 }, { B_DIRECT_SPECIFIER, 0 }, @@ -54,46 +59,52 @@ static property_info sProperties[] = { }, { "Selection", { B_GET_PROPERTY, 0 }, { B_DIRECT_SPECIFIER, 0 }, - "Returns int32 indices of all items in the selection.", 0, { B_INT32_TYPE } + "Returns int32 indices of all items in the selection.", 0, + { B_INT32_TYPE } }, - { "Selection", { B_SET_PROPERTY, 0 }, { B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, - B_RANGE_SPECIFIER, B_REVERSE_RANGE_SPECIFIER, 0 }, - "Extends current selection or deselects specified items. Boolean field \"data\" " - "chooses selection or deselection.", 0, { B_BOOL_TYPE } + { "Selection", { B_SET_PROPERTY, 0 }, { B_INDEX_SPECIFIER, + B_REVERSE_INDEX_SPECIFIER, B_RANGE_SPECIFIER, + B_REVERSE_RANGE_SPECIFIER, 0 }, + "Extends current selection or deselects specified items. Boolean field " + "\"data\" chooses selection or deselection.", 0, { B_BOOL_TYPE } }, { "Selection", { B_SET_PROPERTY, 0 }, { B_DIRECT_SPECIFIER, 0 }, - "Select or deselect all items in the selection. Boolean field \"data\" chooses " - "selection or deselection.", 0, { B_BOOL_TYPE } + "Select or deselect all items in the selection. Boolean field \"data\" " + "chooses selection or deselection.", 0, { B_BOOL_TYPE } }, }; BListView::BListView(BRect frame, const char* name, list_view_type type, - uint32 resizingMode, uint32 flags) - : BView(frame, name, resizingMode, flags) + uint32 resizingMode, uint32 flags) + : + BView(frame, name, resizingMode, flags) { _InitObject(type); } BListView::BListView(const char* name, list_view_type type, uint32 flags) - : BView(name, flags) + : + BView(name, flags) { _InitObject(type); } BListView::BListView(list_view_type type) - : BView(NULL, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE) + : + BView(NULL, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE) { _InitObject(type); } BListView::BListView(BMessage* archive) - : BView(archive) + : + BView(archive) { int32 listType; archive->FindInt32("_lv_type", &listType); @@ -102,24 +113,24 @@ BListView::BListView(BMessage* archive) int32 i = 0; BMessage subData; while (archive->FindMessage("_l_items", i++, &subData) == B_OK) { - BArchivable *object = instantiate_object(&subData); - if (!object) + BArchivable* object = instantiate_object(&subData); + if (object == NULL) continue; - BListItem *item = dynamic_cast(object); - if (item) + BListItem* item = dynamic_cast(object); + if (item != NULL) AddItem(item); } if (archive->HasMessage("_msg")) { - BMessage *invokationMessage = new BMessage; + BMessage* invokationMessage = new BMessage; archive->FindMessage("_msg", invokationMessage); SetInvocationMessage(invokationMessage); } if (archive->HasMessage("_2nd_msg")) { - BMessage *selectionMessage = new BMessage; + BMessage* selectionMessage = new BMessage; archive->FindMessage("_2nd_msg", selectionMessage); SetSelectionMessage(selectionMessage); @@ -157,7 +168,7 @@ BListView::Archive(BMessage* archive, bool deep) const status = archive->AddInt32("_lv_type", fListType); if (status == B_OK && deep) { - BListItem *item; + BListItem* item; int32 i = 0; while ((item = ItemAt(i++))) { @@ -377,11 +388,10 @@ BListView::MessageReceived(BMessage* msg) void -BListView::KeyDown(const char *bytes, int32 numBytes) +BListView::KeyDown(const char* bytes, int32 numBytes) { - bool extend - = fListType == B_MULTIPLE_SELECTION_LIST - && (modifiers() & B_SHIFT_KEY) != 0; + bool extend = fListType == B_MULTIPLE_SELECTION_LIST + && (modifiers() & B_SHIFT_KEY) != 0; switch (bytes[0]) { case B_UP_ARROW: @@ -425,6 +435,7 @@ BListView::KeyDown(const char *bytes, int32 numBytes) fAnchorIndex = 0; } else Select(0, false); + ScrollToSelection(); break; case B_END: @@ -433,6 +444,7 @@ BListView::KeyDown(const char *bytes, int32 numBytes) fAnchorIndex = CountItems() - 1; } else Select(CountItems() - 1, false); + ScrollToSelection(); break; @@ -475,7 +487,7 @@ BListView::MouseDown(BPoint point) Window()->UpdateIfNeeded(); } - BMessage *message = Looper()->CurrentMessage(); + BMessage* message = Looper()->CurrentMessage(); int32 index = IndexOf(point); // If the user double (or more) clicked within the current selection, @@ -494,8 +506,9 @@ BListView::MouseDown(BPoint point) if (timeDelta < doubleClickSpeed && fabs(delta.x) < kDoubleClickTresh && fabs(delta.y) < kDoubleClickTresh - && fTrack->item_index == index) + && fTrack->item_index == index) { doubleClick = true; + } if (doubleClick && index >= fFirstSelected && index <= fLastSelected) { fTrack->drag_start.Set(INT32_MAX, INT32_MAX); @@ -518,8 +531,10 @@ BListView::MouseDown(BPoint point) if (fListType == B_MULTIPLE_SELECTION_LIST) { if (modifiers & B_SHIFT_KEY) { // select entire block - // TODO: maybe review if we want it like in Tracker (anchor item) - Select(min_c(index, fFirstSelected), max_c(index, fLastSelected)); + // TODO: maybe review if we want it like in Tracker + // (anchor item) + Select(min_c(index, fFirstSelected), max_c(index, + fLastSelected)); } else { if (modifiers & B_COMMAND_KEY) { // toggle selection state of clicked item (like in Tracker) @@ -528,9 +543,8 @@ BListView::MouseDown(BPoint point) Deselect(index); else Select(index, true); - } else { + } else Select(index); - } } } else { // toggle selection state of clicked item @@ -539,15 +553,13 @@ BListView::MouseDown(BPoint point) else Select(index); } - } else { - if (!(modifiers & B_COMMAND_KEY)) - DeselectAll(); - } + } else if ((modifiers & B_COMMAND_KEY) == 0) + DeselectAll(); } -// MouseUp + void -BListView::MouseUp(BPoint pt) +BListView::MouseUp(BPoint where) { fTrack->try_drag = false; } @@ -591,7 +603,7 @@ BListView::ResizeToPreferred() void -BListView::GetPreferredSize(float* _width, float* _height) +BListView::GetPreferredSize(float *_width, float *_height) { int32 count = CountItems(); @@ -607,9 +619,8 @@ BListView::GetPreferredSize(float* _width, float* _height) *_width = maxWidth; if (_height != NULL) *_height = ItemAt(count - 1)->Bottom(); - } else { + } else BView::GetPreferredSize(_width, _height); - } } @@ -769,8 +780,8 @@ BListView::AddList(BList* list) BListItem* BListView::RemoveItem(int32 index) { - BListItem *item = ItemAt(index); - if (!item) + BListItem* item = ItemAt(index); + if (item == NULL) return NULL; if (item->IsSelected()) @@ -798,7 +809,7 @@ BListView::RemoveItem(int32 index) bool -BListView::RemoveItem(BListItem *item) +BListView::RemoveItem(BListItem* item) { return BListView::RemoveItem(IndexOf(item)) != NULL; } @@ -819,6 +830,7 @@ BListView::RemoveItems(int32 index, int32 count) fList.RemoveItems(index, count); if (index < fList.CountItems()) _RecalcItemTops(index); + Invalidate(); return true; } @@ -873,9 +885,10 @@ BListView::SelectionCommand() const void BListView::SetListType(list_view_type type) { - if (fListType == B_MULTIPLE_SELECTION_LIST && - type == B_SINGLE_SELECTION_LIST) + if (fListType == B_MULTIPLE_SELECTION_LIST + && type == B_SINGLE_SELECTION_LIST) { Select(CurrentSelection(0)); + } fListType = type; } @@ -903,6 +916,7 @@ BListView::IndexOf(BListItem *item) const int32 index = IndexOf(BPoint(0.0, item->Top())); if (index >= 0 && fList.ItemAt(index) == item) return index; + return -1; } } @@ -918,6 +932,7 @@ BListView::IndexOf(BPoint point) const int32 mid = -1; float frameTop = -1.0; float frameBottom = 1.0; + // binary search the list while (high >= low) { mid = (low + high) / 2; @@ -1052,8 +1067,8 @@ BListView::Select(int32 start, int32 finish, bool extend) bool BListView::IsItemSelected(int32 index) const { - BListItem *item = ItemAt(index); - if (item) + BListItem* item = ItemAt(index); + if (item != NULL) return item->IsSelected(); return false; @@ -1206,7 +1221,7 @@ BListView::MoveItem(int32 from, int32 to) bool -BListView::ReplaceItem(int32 index, BListItem *item) +BListView::ReplaceItem(int32 index, BListItem* item) { MiscData data; @@ -1499,7 +1514,8 @@ BListView::_Select(int32 index, bool extend) } -/*! Selects the items between \a from and \a to, and returns \c true in +/*! + Selects the items between \a from and \a to, and returns \c true in case the selection was changed because of this method. If \a extend is \c false, all previously selected items are deselected. */ @@ -1687,8 +1703,10 @@ BListView::_SwapItems(int32 a, int32 b) int32 first = min_c(a, b); int32 last = max_c(a, b); if (ItemAt(a)->IsSelected() != ItemAt(b)->IsSelected()) { - if (first < fFirstSelected || last > fLastSelected) - _RescanSelection(min_c(first, fFirstSelected), max_c(last, fLastSelected)); + if (first < fFirstSelected || last > fLastSelected) { + _RescanSelection(min_c(first, fFirstSelected), + max_c(last, fLastSelected)); + } // though the actually selected items stayed the // same, the selection has still changed SelectionChanged(); @@ -1749,9 +1767,9 @@ BListView::_MoveItem(int32 from, int32 to) bool -BListView::_ReplaceItem(int32 index, BListItem *item) +BListView::_ReplaceItem(int32 index, BListItem* item) { - if (!item) + if (item == NULL) return false; BListItem* old = ItemAt(index); @@ -1848,4 +1866,3 @@ BListView::_RecalcItemTops(int32 start, int32 end) top += ceilf(item->Height()); } } - diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 0485f9779b..e8b7283e72 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1729,7 +1729,8 @@ BMenu::_Track(int* action, long start) GetMouse(&newLocation, &newButtons, true); UnlockLooper(); } while (newLocation == location && newButtons == buttons - && !(item && item->Submenu() != NULL) + && !(item != NULL && item->Submenu() != NULL + && item->Submenu()->Window() == NULL) && fState == MENU_STATE_TRACKING); if (newLocation != location || newButtons != buttons) { @@ -2118,9 +2119,18 @@ BMenu::_ComputeLayout(int32 index, bool bestFit, bool moveItems, switch (fLayout) { case B_ITEMS_IN_COLUMN: - _ComputeColumnLayout(index, bestFit, moveItems, frame); - break; + { + BRect parentFrame; + BRect* overrideFrame = NULL; + if (dynamic_cast<_BMCMenuBar_*>(Supermenu()) != NULL) { + parentFrame = Supermenu()->Bounds(); + overrideFrame = &parentFrame; + } + _ComputeColumnLayout(index, bestFit, moveItems, overrideFrame, + frame); + break; + } case B_ITEMS_IN_ROW: _ComputeRowLayout(index, bestFit, moveItems, frame); break; @@ -2163,7 +2173,7 @@ BMenu::_ComputeLayout(int32 index, bool bestFit, bool moveItems, void BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems, - BRect& frame) + BRect* overrideFrame, BRect& frame) { BFont font; GetFont(&font); @@ -2173,7 +2183,9 @@ BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems, bool option = false; if (index > 0) frame = ItemAt(index - 1)->Frame(); - else + else if (overrideFrame != NULL) { + frame.Set(0, 0, overrideFrame->right, -1); + } else frame.Set(0, 0, 0, -1); for (; index < fItems.CountItems(); index++) { @@ -2325,13 +2337,12 @@ BMenu::_CalcFrame(BPoint where, bool* scrollOn) BMenu* superMenu = Supermenu(); BMenuItem* superItem = Superitem(); - bool scroll = false; - // TODO: Horrible hack: // When added to a BMenuField, a BPopUpMenu is the child of // a _BMCMenuBar_ to "fake" the menu hierarchy - if (superMenu == NULL || superItem == NULL - || dynamic_cast<_BMCMenuBar_*>(superMenu) != NULL) { + bool inMenuField = dynamic_cast<_BMCMenuBar_*>(superMenu) != NULL; + bool scroll = false; + if (superMenu == NULL || superItem == NULL || inMenuField) { // just move the window on screen if (frame.bottom > screenFrame.bottom) diff --git a/src/kits/interface/ScrollBar.cpp b/src/kits/interface/ScrollBar.cpp index 1d6fd3988f..faafab4342 100644 --- a/src/kits/interface/ScrollBar.cpp +++ b/src/kits/interface/ScrollBar.cpp @@ -965,11 +965,13 @@ BScrollBar::Draw(BRect updateRect) bottomOfThumb, updateRect, normal, flags, fOrientation); } + rgb_color thumbColor = ui_color(B_SCROLL_BAR_THUMB_COLOR); + // Draw scroll thumb if (enabled) { // fill the clickable surface of the thumb be_control_look->DrawButtonBackground(this, rect, updateRect, - normal, 0, BControlLook::B_ALL_BORDERS, fOrientation); + thumbColor, 0, BControlLook::B_ALL_BORDERS, fOrientation); // TODO: Add the other thumb styles - dots and lines } else { if (fMin >= fMax || fProportion >= 1.0 || fProportion < 0.0) { diff --git a/src/kits/locale/UnicodeChar.cpp b/src/kits/locale/UnicodeChar.cpp index a86192e782..bdb032c061 100644 --- a/src/kits/locale/UnicodeChar.cpp +++ b/src/kits/locale/UnicodeChar.cpp @@ -1,234 +1,18 @@ -/* -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ - -/* Reads the information out of the data files created by (an edited version of) - * IBM's ICU genprops utility. The BUnicodeChar class is mostly the counterpart - * to ICU's uchar module, but is not as huge or broad as that one. +/* + * Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. * - * Note, it probably won't be able to handle the output of the orginal genprops - * tool and vice versa - only use the tool provided with this project to create - * the Unicode property file. - * However, the algorithmic idea behind the property file is still the same as - * found in ICU - nothing important has been changed, so more recent versions - * of genprops tool/data can probably be ported without too much effort. + * Authors: + * Axel Dörfler, axeld@pinc-software.de + * Siarzhuk Zharski, zharik@gmx.li * - * In case no property file can be found it will still provide basic services - * for the Latin-1 part of the character tables. */ -#include - #include -#include -#include -#include - - -#define FLAG(n) ((uint32)1 << (n)) -enum { - UF_UPPERCASE = FLAG(B_UNICODE_UPPERCASE_LETTER), - UF_LOWERCASE = FLAG(B_UNICODE_LOWERCASE_LETTER), - UF_TITLECASE = FLAG(B_UNICODE_TITLECASE_LETTER), - UF_MODIFIER_LETTER = FLAG(B_UNICODE_MODIFIER_LETTER), - UF_OTHER_LETTER = FLAG(B_UNICODE_OTHER_LETTER), - UF_DECIMAL_NUMBER = FLAG(B_UNICODE_DECIMAL_DIGIT_NUMBER), - UF_OTHER_NUMBER = FLAG(B_UNICODE_OTHER_NUMBER), - UF_LETTER_NUMBER = FLAG(B_UNICODE_LETTER_NUMBER) -}; - - -static uint32 gStaticProps32Table[] = { - /* 0x00 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x04 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x08 */ 0x48f, 0x20c, 0x1ce, 0x20c, - /* 0x0c */ 0x24d, 0x1ce, 0x48f, 0x48f, - /* 0x10 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x14 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x18 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x1c */ 0x1ce, 0x1ce, 0x1ce, 0x20c, - /* 0x20 */ 0x24c, 0x297, 0x297, 0x117, - /* 0x24 */ 0x119, 0x117, 0x297, 0x297, - /* 0x28 */ 0x100a94, 0xfff00a95, 0x297, 0x118, - /* 0x2c */ 0x197, 0x113, 0x197, 0xd7, - /* 0x30 */ 0x89, 0x100089, 0x200089, 0x300089, - /* 0x34 */ 0x400089, 0x500089, 0x600089, 0x700089, - /* 0x38 */ 0x800089, 0x900089, 0x197, 0x297, - /* 0x3c */ 0x200a98, 0x298, 0xffe00a98, 0x297, - /* 0x40 */ 0x297, 0x2000001, 0x2000001, 0x2000001, - /* 0x44 */ 0x2000001, 0x2000001, 0x2000001, 0x2000001, - /* 0x48 */ 0x2000001, 0x2000001, 0x2000001, 0x2000001, - /* 0x4c */ 0x2000001, 0x2000001, 0x2000001, 0x2000001, - /* 0x50 */ 0x2000001, 0x2000001, 0x2000001, 0x2000001, - /* 0x54 */ 0x2000001, 0x2000001, 0x2000001, 0x2000001, - /* 0x58 */ 0x2000001, 0x2000001, 0x2000001, 0x200a94, - /* 0x5c */ 0x297, 0xffe00a95, 0x29a, 0x296, - /* 0x60 */ 0x29a, 0x2000002, 0x2000002, 0x2000002, - /* 0x64 */ 0x2000002, 0x2000002, 0x2000002, 0x2000002, - /* 0x68 */ 0x2000002, 0x2000002, 0x2000002, 0x2000002, - /* 0x6c */ 0x2000002, 0x2000002, 0x2000002, 0x2000002, - /* 0x70 */ 0x2000002, 0x2000002, 0x2000002, 0x2000002, - /* 0x74 */ 0x2000002, 0x2000002, 0x2000002, 0x2000002, - /* 0x78 */ 0x2000002, 0x2000002, 0x2000002, 0x200a94, - /* 0x7c */ 0x298, 0xffe00a95, 0x298, 0x48f, - /* 0x80 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x84 */ 0x48f, 0x1ce, 0x48f, 0x48f, - /* 0x88 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x8c */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x90 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x94 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x98 */ 0x48f, 0x48f, 0x48f, 0x48f, - /* 0x9c */ 0x48f, 0x48f, 0x48f, 0x48f -}; - -enum { - INDEX_STAGE_2_BITS, - INDEX_STAGE_3_BITS, - INDEX_EXCEPTIONS, - INDEX_STAGE_3_INDEX, - INDEX_PROPS, - INDEX_UCHARS -}; - -/* constants and macros for access to the data */ -enum { - EXC_UPPERCASE, - EXC_LOWERCASE, - EXC_TITLECASE, - EXC_DIGIT_VALUE, - EXC_NUMERIC_VALUE, - EXC_DENOMINATOR_VALUE, - EXC_MIRROR_MAPPING, - EXC_SPECIAL_CASING, - EXC_CASE_FOLDING -}; - -enum { - EXCEPTION_SHIFT = 5, - BIDI_SHIFT, - MIRROR_SHIFT = BIDI_SHIFT + 5, - VALUE_SHIFT = 20, - - VALUE_BITS = 32 - VALUE_SHIFT -}; - -/* number of bits in an 8-bit integer value */ -#define EXC_GROUP 8 -static uint8 gFlagsOffset[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - -#ifdef UCHAR_VARIABLE_TRIE_BITS - // access values calculated from indices - static uint16_t stage23Bits, stage2Mask, stage3Mask; -# define sStage3Bits indexes[INDEX_STAGE_3_BITS] -#else - // Use hardcoded bit distribution for the trie table access -# define sStage23Bits 10 -# define sStage2Mask 0x3f -# define sStage3Mask 0xf -# define sStage3Bits 4 -#endif - - -/** We need to change the char category for ISO 8 controls, since the - * genprops utility we got from IBM's ICU apparently changes it for - * some characters. - */ - -static inline bool -isISO8Control(uint32 c) -{ - return ((uint32)c < 0x20 || (uint32)(c - 0x7f) <= 0x20); -} - - -static inline uint32 -getProperties(uint32 c) -{ - if (c > 0x10ffff) - return 0; - - // TODO : Data from unicode - - return c > 0x9f ? 0 : gStaticProps32Table[c]; -} - - -static inline uint8 -getCategory(uint32 properties) -{ - return properties & 0x1f; -} - - -static inline bool -propertyIsException(uint32 properties) -{ - return properties & (1UL << EXCEPTION_SHIFT); -} - - -static inline uint32 -getUnsignedValue(uint32 properties) -{ - return properties >> VALUE_SHIFT; -} - - -static inline uint32 -getSignedValue(uint32 properties) -{ - return (int32)properties >> VALUE_SHIFT; -} - - -static inline uint32 * -getExceptions(uint32 properties) -{ - // TODO : data from unicode - return 0; -} - - -static inline bool -haveExceptionValue(uint32 flags,int16 index) -{ - return flags & (1UL << index); -} - - -static inline void -addExceptionOffset(uint32 &flags, int16 &index, uint32 **offset) -{ - if (index >= EXC_GROUP) { - *offset += gFlagsOffset[flags & ((1 << EXC_GROUP) - 1)]; - flags >>= EXC_GROUP; - index -= EXC_GROUP; - } - *offset += gFlagsOffset[flags & ((1 << index) - 1)]; -} - - -// #pragma mark - +#include +#include BUnicodeChar::BUnicodeChar() @@ -236,382 +20,247 @@ BUnicodeChar::BUnicodeChar() } -bool -BUnicodeChar::IsAlpha(uint32 c) -{ - BUnicodeChar(); - return (FLAG(getCategory(getProperties(c))) - & (UF_UPPERCASE | UF_LOWERCASE | UF_TITLECASE | UF_MODIFIER_LETTER | UF_OTHER_LETTER) - ) != 0; -} - - -/** Returns the type code of the specified unicode character */ +// Returns the general category value for the code point. int8 BUnicodeChar::Type(uint32 c) { BUnicodeChar(); - return (int8)getCategory(getProperties(c)); + return u_charType(c); } -bool -BUnicodeChar::IsLower(uint32 c) +// Determines whether the specified code point is a letter character. +// True for general categories "L" (letters). +bool +BUnicodeChar::IsAlpha(uint32 c) { BUnicodeChar(); - return getCategory(getProperties(c)) == B_UNICODE_LOWERCASE_LETTER; + return u_isalpha(c); } -bool -BUnicodeChar::IsUpper(uint32 c) -{ - BUnicodeChar(); - return getCategory(getProperties(c)) == B_UNICODE_UPPERCASE_LETTER; -} - - -bool -BUnicodeChar::IsTitle(uint32 c) -{ - BUnicodeChar(); - return getCategory(getProperties(c)) == B_UNICODE_TITLECASE_LETTER; -} - - -bool -BUnicodeChar::IsDigit(uint32 c) -{ - BUnicodeChar(); - return (FLAG(getCategory(getProperties(c))) - & (UF_DECIMAL_NUMBER | UF_OTHER_NUMBER | UF_LETTER_NUMBER) - ) != 0; -} - - -bool +// Determines whether the specified code point is an alphanumeric character +// (letter or digit). +// True for characters with general categories +// "L" (letters) and "Nd" (decimal digit numbers). +bool BUnicodeChar::IsAlNum(uint32 c) { BUnicodeChar(); - return (FLAG(getCategory(getProperties(c))) - & (UF_DECIMAL_NUMBER | UF_OTHER_NUMBER | UF_LETTER_NUMBER | UF_UPPERCASE - | UF_LOWERCASE | UF_TITLECASE | UF_MODIFIER_LETTER | UF_OTHER_LETTER) - ) != 0; + return u_isalnum(c); } -bool +// Check if a code point has the Lowercase Unicode property (UCHAR_LOWERCASE). +bool +BUnicodeChar::IsLower(uint32 c) +{ + BUnicodeChar(); + return u_isULowercase(c); +} + + +// Check if a code point has the Uppercase Unicode property (UCHAR_UPPERCASE). +bool +BUnicodeChar::IsUpper(uint32 c) +{ + BUnicodeChar(); + return u_isUUppercase(c); +} + + +// Determines whether the specified code point is a titlecase letter. +// True for general category "Lt" (titlecase letter). +bool +BUnicodeChar::IsTitle(uint32 c) +{ + BUnicodeChar(); + return u_istitle(c); +} + + +// Determines whether the specified code point is a digit character. +// True for characters with general category "Nd" (decimal digit numbers). +// Beginning with Unicode 4, this is the same as +// testing for the Numeric_Type of Decimal. +bool +BUnicodeChar::IsDigit(uint32 c) +{ + BUnicodeChar(); + return u_isdigit(c); +} + + +// Determines whether the specified code point is a hexadecimal digit. +// This is equivalent to u_digit(c, 16)>=0. +// True for characters with general category "Nd" (decimal digit numbers) +// as well as Latin letters a-f and A-F in both ASCII and Fullwidth ASCII. +// (That is, for letters with code points +// 0041..0046, 0061..0066, FF21..FF26, FF41..FF46.) +bool +BUnicodeChar::IsHexDigit(uint32 c) +{ + BUnicodeChar(); + return u_isxdigit(c); +} + + +// Determines whether the specified code point is "defined", +// which usually means that it is assigned a character. +// True for general categories other than "Cn" (other, not assigned), +// i.e., true for all code points mentioned in UnicodeData.txt. +bool BUnicodeChar::IsDefined(uint32 c) { BUnicodeChar(); - return getProperties(c) != 0; + return u_isdefined(c); } -/** Returns true if the specified unicode character is a base - * form character that can be used with a diacritic. - * This doesn't mean that the character has to be distinct, - * though. - */ - -bool +// Determines whether the specified code point is a base character. +// True for general categories "L" (letters), "N" (numbers), +// "Mc" (spacing combining marks), and "Me" (enclosing marks). +bool BUnicodeChar::IsBase(uint32 c) { BUnicodeChar(); - return (FLAG(getCategory(getProperties(c))) - & (UF_DECIMAL_NUMBER | UF_OTHER_NUMBER | UF_LETTER_NUMBER - | UF_UPPERCASE | UF_LOWERCASE | UF_TITLECASE - | UF_MODIFIER_LETTER | UF_OTHER_LETTER | FLAG(B_UNICODE_NON_SPACING_MARK) - | FLAG(B_UNICODE_ENCLOSING_MARK) | FLAG(B_UNICODE_COMBINING_SPACING_MARK)) - ) != 0; + return u_isbase(c); } -/** Returns true if the specified unicode character is a - * control character. - */ - -bool +// Determines whether the specified code point is a control character +// (as defined by this function). +// A control character is one of the following: +// - ISO 8-bit control character (U+0000..U+001f and U+007f..U+009f) +// - U_CONTROL_CHAR (Cc) +// - U_FORMAT_CHAR (Cf) +// - U_LINE_SEPARATOR (Zl) +// - U_PARAGRAPH_SEPARATOR (Zp) +bool BUnicodeChar::IsControl(uint32 c) { BUnicodeChar(); - return isISO8Control(c) - || (FLAG(getCategory(getProperties(c))) - & (FLAG(B_UNICODE_CONTROL_CHAR) | FLAG(B_UNICODE_FORMAT_CHAR) - | FLAG(B_UNICODE_LINE_SEPARATOR) | FLAG(B_UNICODE_PARAGRAPH_SEPARATOR)) - ) != 0; + return u_iscntrl(c); } -/** Returns true if the specified unicode character is a - * punctuation character. - */ - +// Determines whether the specified code point is a punctuation character. +// True for characters with general categories "P" (punctuation). bool BUnicodeChar::IsPunctuation(uint32 c) { BUnicodeChar(); - return (FLAG(getCategory(getProperties(c))) - & (FLAG(B_UNICODE_DASH_PUNCTUATION) - | FLAG(B_UNICODE_START_PUNCTUATION) - | FLAG(B_UNICODE_END_PUNCTUATION) - | FLAG(B_UNICODE_CONNECTOR_PUNCTUATION) - | FLAG(B_UNICODE_OTHER_PUNCTUATION)) - ) != 0; + return u_ispunct(c); } -/** Returns true if the specified unicode character is some - * kind of a space character. - */ - -bool +// Determine if the specified code point is a space character according to Java. +// True for characters with general categories "Z" (separators), +// which does not include control codes (e.g., TAB or Line Feed). +bool BUnicodeChar::IsSpace(uint32 c) { BUnicodeChar(); - return (FLAG(getCategory(getProperties(c))) - & (FLAG(B_UNICODE_SPACE_SEPARATOR) - | FLAG(B_UNICODE_LINE_SEPARATOR) - | FLAG(B_UNICODE_PARAGRAPH_SEPARATOR)) - ) != 0; + return u_isJavaSpaceChar(c); } -/** Returns true if the specified unicode character is a white - * space character. - * This is essentially the same as IsSpace(), but excludes all - * non-breakable spaces. - */ - -bool +// Determines if the specified code point is a whitespace character +// A character is considered to be a whitespace character if and only +// if it satisfies one of the following criteria: +// - It is a Unicode Separator character (categories "Z" = "Zs" or "Zl" or "Zp"), +// but is not also a non-breaking space (U+00A0 NBSP or U+2007 Figure Space +// or U+202F Narrow NBSP). +// - It is U+0009 HORIZONTAL TABULATION. +// - It is U+000A LINE FEED. +// - It is U+000B VERTICAL TABULATION. +// - It is U+000C FORM FEED. +// - It is U+000D CARRIAGE RETURN. +// - It is U+001C FILE SEPARATOR. +// - It is U+001D GROUP SEPARATOR. +// - It is U+001E RECORD SEPARATOR. +// - It is U+001F UNIT SEPARATOR. +bool BUnicodeChar::IsWhitespace(uint32 c) { BUnicodeChar(); - return (FLAG(getCategory(getProperties(c))) - & (FLAG(B_UNICODE_SPACE_SEPARATOR) - | FLAG(B_UNICODE_LINE_SEPARATOR) - | FLAG(B_UNICODE_PARAGRAPH_SEPARATOR)) - ) != 0 && c != 0xa0 && c != 0x202f && c != 0xfeff; // exclude non-breakable spaces + return u_isWhitespace(c); } -/** Returns true if the specified unicode character is printable. - */ - -bool +// Determines whether the specified code point is a printable character. +// True for general categories other than "C" (controls). +bool BUnicodeChar::IsPrintable(uint32 c) { BUnicodeChar(); - return !isISO8Control(c) - && (FLAG(getCategory(getProperties(c))) - & ~(FLAG(B_UNICODE_UNASSIGNED) | FLAG(B_UNICODE_CONTROL_CHAR) - | FLAG(B_UNICODE_FORMAT_CHAR) | FLAG(B_UNICODE_PRIVATE_USE_CHAR) - | FLAG(B_UNICODE_SURROGATE) | FLAG(B_UNICODE_GENERAL_OTHER_TYPES) - | FLAG(31)) - ) != 0; + return u_isprint(c); } // #pragma mark - - -/** Transforms the specified unicode character to lowercase. - */ - -uint32 +uint32 BUnicodeChar::ToLower(uint32 c) { BUnicodeChar(); - - uint32 props = getProperties(c); - - if (!propertyIsException(props)) { - if (FLAG(getCategory(props)) & (UF_UPPERCASE | UF_TITLECASE)) - return c + getSignedValue(props); - } else { - uint32 *exceptions = getExceptions(props); - uint32 firstExceptionValue = *exceptions; - - if (haveExceptionValue(firstExceptionValue, EXC_LOWERCASE)) { - int16 index = EXC_LOWERCASE; - addExceptionOffset(firstExceptionValue, index, &++exceptions); - return *exceptions; - } - } - // no mapping found, just return the character unchanged - return c; + return u_tolower(c); } -/** Transforms the specified unicode character to uppercase. - */ - -uint32 +uint32 BUnicodeChar::ToUpper(uint32 c) { BUnicodeChar(); - - uint32 props = getProperties(c); - - if (!propertyIsException(props)) { - if (getCategory(props) == B_UNICODE_LOWERCASE_LETTER) - return c - getSignedValue(props); - } else { - uint32 *exceptions = getExceptions(props); - uint32 firstExceptionValue = *exceptions; - - if (haveExceptionValue(firstExceptionValue, EXC_UPPERCASE)) { - int16 index = EXC_UPPERCASE; - ++exceptions; - addExceptionOffset(firstExceptionValue, index, &exceptions); - return *exceptions; - } - } - // no mapping found, just return the character unchanged - return c; + return u_toupper(c); } -/** Transforms the specified unicode character to title case. - */ - -uint32 +uint32 BUnicodeChar::ToTitle(uint32 c) { BUnicodeChar(); - - uint32 props = getProperties(c); - - if (!propertyIsException(props)) { - if (getCategory(props) == B_UNICODE_LOWERCASE_LETTER) { - // here, titlecase is the same as uppercase - return c - getSignedValue(props); - } - } else { - uint32 *exceptions = getExceptions(props); - uint32 firstExceptionValue = *exceptions; - - if (haveExceptionValue(firstExceptionValue, EXC_TITLECASE)) { - int16 index = EXC_TITLECASE; - addExceptionOffset(firstExceptionValue, index, &++exceptions); - return (uint32)*exceptions; - } else if (haveExceptionValue(firstExceptionValue, EXC_UPPERCASE)) { - // here, titlecase is the same as uppercase - int16 index = EXC_UPPERCASE; - addExceptionOffset(firstExceptionValue, index, &++exceptions); - return *exceptions; - } - } - // no mapping found, just return the character unchanged - return c; + return u_totitle(c); } -int32 +int32 BUnicodeChar::DigitValue(uint32 c) { BUnicodeChar(); + return u_digit(c, 10); +} - uint32 props = getProperties(c); - if (!propertyIsException(props)) { - if (getCategory(props) == B_UNICODE_DECIMAL_DIGIT_NUMBER) - return getSignedValue(props); - } else { - uint32 *exceptions = getExceptions(props); - uint32 firstExceptionValue = *exceptions; - - if (haveExceptionValue(firstExceptionValue, EXC_DIGIT_VALUE)) { - int16 index = EXC_DIGIT_VALUE; - addExceptionOffset(firstExceptionValue, index, &++exceptions); - - int32 value = (int32)(int16)*exceptions; - // the digit value is in the lower 16 bits - if (value != -1) - return value; - } - } - - // If there is no value in the properties table, - // then check for some special characters - switch (c) { - case 0x3007: return 0; - case 0x4e00: return 1; - case 0x4e8c: return 2; - case 0x4e09: return 3; - case 0x56d8: return 4; - case 0x4e94: return 5; - case 0x516d: return 6; - case 0x4e03: return 7; - case 0x516b: return 8; - case 0x4e5d: return 9; - default: return -1; - } +unicode_east_asian_width +BUnicodeChar::EastAsianWidth(uint32 c) +{ + return (unicode_east_asian_width)u_getIntPropertyValue(c, + UCHAR_EAST_ASIAN_WIDTH); } void BUnicodeChar::ToUTF8(uint32 c, char **out) { - char *s = *out; - - if (c < 0x80) - *(s++) = c; - else if (c < 0x800) { - *(s++) = 0xc0 | (c >> 6); - *(s++) = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - *(s++) = 0xe0 | (c >> 12); - *(s++) = 0x80 | ((c >> 6) & 0x3f); - *(s++) = 0x80 | (c & 0x3f); - } else if (c <= 0x10ffff) { - *(s++) = 0xf0 | (c >> 18); - *(s++) = 0x80 | ((c >> 12) & 0x3f); - *(s++) = 0x80 | ((c >> 6) & 0x3f); - *(s++) = 0x80 | (c & 0x3f); - } - *out = s; + int i = 0; + U8_APPEND_UNSAFE(*out, i, c); + *out += i; } -uint32 +uint32 BUnicodeChar::FromUTF8(const char **in) { - uint8 *bytes = (uint8 *)*in; - if (bytes == NULL) - return 0; + int i = 0; + uint32 c = 0; + U8_NEXT_UNSAFE(*in, i, c); + *in += i; - int32 length; - uint8 mask = 0x1f; - - switch (bytes[0] & 0xf0) { - case 0xc0: - case 0xd0: length = 2; break; - case 0xe0: length = 3; break; - case 0xf0: - mask = 0x0f; - length = 4; - break; - default: - // valid 1-byte character - // and invalid characters - (*in)++; - return bytes[0]; - } - uint32 c = bytes[0] & mask; - int32 i = 1; - for (;i < length && (bytes[i] & 0x80) > 0;i++) - c = (c << 6) | (bytes[i] & 0x3f); - - if (i < length) { - // invalid character - (*in)++; - return (uint32)bytes[0]; - } - *in += length; return c; } + size_t BUnicodeChar::UTF8StringLength(const char *str) { @@ -623,6 +272,7 @@ BUnicodeChar::UTF8StringLength(const char *str) return len; } + size_t BUnicodeChar::UTF8StringLength(const char *str, size_t maxLength) { @@ -633,4 +283,3 @@ BUnicodeChar::UTF8StringLength(const char *str, size_t maxLength) } return len; } - diff --git a/src/kits/network/libbind/irs/getaddrinfo.c b/src/kits/network/libbind/irs/getaddrinfo.c index 1839ba48e1..b95e6cd21c 100644 --- a/src/kits/network/libbind/irs/getaddrinfo.c +++ b/src/kits/network/libbind/irs/getaddrinfo.c @@ -328,6 +328,7 @@ getaddrinfo(hostname, servname, hints, res) struct addrinfo ai, ai0, *afai = NULL; struct addrinfo *pai; const struct explore *ex; + struct net_data *net_data; memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; @@ -501,6 +502,11 @@ getaddrinfo(hostname, servname, hints, res) if (hostname == NULL) SETERROR(EAI_NONAME); + /* init after numeric lookups to avoid recursion in resolv.conf */ + net_data = init(); + if ((net_data->res->options & RES_USE_INET4) && ai0.ai_family == PF_UNSPEC) + ai0.ai_family = PF_INET; + /* * hostname as alphabetical name. * We'll make sure that diff --git a/src/kits/network/libbind/resolv/res_debug.c b/src/kits/network/libbind/resolv/res_debug.c index 8446bbbe4e..3e1d2c687c 100644 --- a/src/kits/network/libbind/resolv/res_debug.c +++ b/src/kits/network/libbind/resolv/res_debug.c @@ -680,6 +680,7 @@ p_option(u_long option) { case RES_INSECURE2: return "insecure2"; case RES_NOALIASES: return "noaliases"; case RES_USE_INET6: return "inet6"; + case RES_USE_INET4: return "inet4"; #ifdef RES_USE_EDNS0 /*%< KAME extension */ case RES_USE_EDNS0: return "edns0"; case RES_NSID: return "nsid"; diff --git a/src/kits/network/libbind/resolv/res_init.c b/src/kits/network/libbind/resolv/res_init.c index b96d8517ce..213e8d9001 100644 --- a/src/kits/network/libbind/resolv/res_init.c +++ b/src/kits/network/libbind/resolv/res_init.c @@ -594,6 +594,8 @@ res_setoptions(res_state statp, const char *options, const char *source) statp->options |= RES_NOTLDQUERY; } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { statp->options |= RES_USE_INET6; + } else if (!strncmp(cp, "inet4", sizeof("inet4") - 1)) { + statp->options |= RES_USE_INET4; } else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) { statp->options |= RES_ROTATE; } else if (!strncmp(cp, "no-check-names", diff --git a/src/kits/support/Referenceable.cpp b/src/kits/support/Referenceable.cpp index 1aaedec5d9..8f21ea888e 100644 --- a/src/kits/support/Referenceable.cpp +++ b/src/kits/support/Referenceable.cpp @@ -6,10 +6,14 @@ #include +#ifdef DEBUG +#include +#endif + #include //#define TRACE_REFERENCEABLE -#ifdef TRACE_REFERENCEABLE +#if defined(TRACE_REFERENCEABLE) && defined(_KERNEL_MODE) # include # define TRACE(x, ...) ktrace_printf(x, __VA_ARGS__); #else @@ -28,6 +32,7 @@ BReferenceable::~BReferenceable() { #ifdef DEBUG bool enterDebugger = false; + char message[256]; if (fReferenceCount == 1) { // Simple heuristic to test if this object was allocated // on the stack: check if this is within 1KB in either @@ -36,7 +41,7 @@ BReferenceable::~BReferenceable() // imply the object was allocated/destroyed on the stack // without any references being acquired or released. char test; - size_t testOffset = (addr_t)this - (addr_t)&test; + ssize_t testOffset = (addr_t)this - (addr_t)&test; if (testOffset > 1024 || -testOffset > 1024) { // might still be a stack object, check the thread's // stack range to be sure. @@ -44,14 +49,21 @@ BReferenceable::~BReferenceable() status_t result = get_thread_info(find_thread(NULL), &info); if (result != B_OK || this < info.stack_base || this > info.stack_end) { + snprintf(message, sizeof(message), "Deleted referenceable " + "object that's not on the stack (this: %p, stack_base: %p," + " stack_end: %p)\n", this, info.stack_base, + info.stack_end); enterDebugger = true; } } - } else if (fReferenceCount != 0) + } else if (fReferenceCount != 0) { + snprintf(message, sizeof(message), "Deleted referenceable object %p with " + "non-zero reference count (%" B_PRId32 ")\n", this, fReferenceCount); enterDebugger = true; + } if (enterDebugger) - debugger("Deleted referenceable object with non-zero ref count."); + debugger(message); #endif } diff --git a/src/kits/textencoding/character_sets.cpp b/src/kits/textencoding/character_sets.cpp index 660973fc0d..ac72fd2bb8 100644 --- a/src/kits/textencoding/character_sets.cpp +++ b/src/kits/textencoding/character_sets.cpp @@ -207,8 +207,8 @@ static const char * windows1251aliases[] = { "cp1251", "cp5347", "ansi-1251", NULL }; -static const BCharacterSet windows1251(18,2251, B_TRANSLATE("Windows Cyrillic (CP 1251)"), - "windows-1251",NULL,windows1251aliases); +static const BCharacterSet windows1251(18,2251, B_TRANSLATE("Windows Cyrillic " + "(CP 1251)"), "windows-1251",NULL,windows1251aliases); static const char * IBM866aliases[] = { // IANA aliases @@ -238,7 +238,8 @@ static const char * eucKRaliases[] = { // IANA aliases "csEUCKR", // java aliases - "ksc5601", "euckr", "ks_c_5601-1987", "ksc5601-1987", "ksc5601_1987", "ksc_5601", "5601", + "ksc5601", "euckr", "ks_c_5601-1987", "ksc5601-1987", + "ksc5601_1987", "ksc_5601", "5601", NULL }; static const BCharacterSet eucKR(21,38, B_TRANSLATE("EUC Korean"), @@ -303,6 +304,17 @@ static const char* kUTF16Aliases[] = { static const BCharacterSet kUTF16(27, 1000, B_TRANSLATE("Unicode"), "UTF-16", "UTF-16", kUTF16Aliases); +static const char* kWindows1250Aliases[] = { + // IANA aliases + "cswindows1250", + // java aliases + "cp1250", + "ms-ee", + NULL +}; +static const BCharacterSet kWindows1250(28, 2250, B_TRANSLATE("Windows Central " + "European (CP 1250)"), "windows-1250", NULL, kWindows1250Aliases); + /** * The following initializes the global character set array. * It is organized by id for efficient retrieval using predefined constants in UTF8.h and Font.h. @@ -323,6 +335,7 @@ const BCharacterSet * character_sets_by_id[] = { // R5 convert_to/from_utf8 encodings end here &big5,&gb18030, &kUTF16, + &kWindows1250, }; const uint32 character_sets_by_id_count = sizeof(character_sets_by_id)/sizeof(const BCharacterSet*); diff --git a/src/kits/tracker/BackgroundImage.cpp b/src/kits/tracker/BackgroundImage.cpp index d46d47ccc6..5a17f182b1 100644 --- a/src/kits/tracker/BackgroundImage.cpp +++ b/src/kits/tracker/BackgroundImage.cpp @@ -197,7 +197,7 @@ BackgroundImage::Show(BackgroundImageInfo* info, BView* view) BRect bitmapBounds(info->fBitmap->Bounds()); BRect destinationBitmapBounds(bitmapBounds); - uint32 tile = 0; + uint32 options = 0; uint32 followFlags = B_FOLLOW_TOP | B_FOLLOW_LEFT; // figure out the display mode and the destination bounds for the bitmap @@ -225,6 +225,7 @@ BackgroundImage::Show(BackgroundImageInfo* info, BView* view) viewBounds.Width(), viewBounds.Height() + overlap); } followFlags = B_FOLLOW_ALL; + options |= B_FILTER_BITMAP_BILINEAR; break; } // else fall thru @@ -237,13 +238,13 @@ BackgroundImage::Show(BackgroundImageInfo* info, BView* view) (viewBounds.Width() - bitmapBounds.Width()) / 2, (viewBounds.Height() - bitmapBounds.Height()) / 2); } - tile = B_TILE_BITMAP; + options |= B_TILE_BITMAP; break; } // switch to the bitmap and force a redraw view->SetViewBitmap(info->fBitmap, bitmapBounds, destinationBitmapBounds, - followFlags, tile); + followFlags, options); view->Invalidate(); fShowingBitmap = info; } diff --git a/src/kits/tracker/DialogPane.cpp b/src/kits/tracker/DialogPane.cpp index ececc6492d..8473c24d52 100644 --- a/src/kits/tracker/DialogPane.cpp +++ b/src/kits/tracker/DialogPane.cpp @@ -34,6 +34,7 @@ All rights reserved. #include "DialogPane.h" +#include #include #include "Thread.h" @@ -73,7 +74,8 @@ ViewList::AddAll(BView* toParent) DialogPane::DialogPane(BRect mode1Frame, BRect mode2Frame, int32 initialMode, const char* name, uint32 followFlags, uint32 flags) - : BView(FrameForMode(initialMode, mode1Frame, mode2Frame, mode2Frame), + : + BView(FrameForMode(initialMode, mode1Frame, mode2Frame, mode2Frame), name, followFlags, flags), fMode(initialMode), fMode1Frame(mode1Frame), @@ -495,103 +497,29 @@ PaneSwitch::Track(BPoint point, uint32) void PaneSwitch::DrawInState(PaneSwitch::State state) { - BRect rect(0, 0, 10, 10); + BRect rect(0, 0, 12, 12); + rect.OffsetBy(-1, -1); - rgb_color outlineColor = {0, 0, 0, 255}; - rgb_color middleColor = state == kPressed ? kHighlightColor : kNormalColor; - - SetDrawingMode(B_OP_COPY); + rgb_color arrowColor = state == kPressed ? kHighlightColor : kNormalColor; + int32 arrowDirection = BControlLook::B_RIGHT_ARROW; + float tint = IsEnabled() && Window()->IsActive() ? B_DARKEN_3_TINT + : B_DARKEN_1_TINT; switch (state) { case kCollapsed: - BeginLineArray(6); - - if (fLeftAligned) { - AddLine(BPoint(rect.left + 3, rect.top + 1), - BPoint(rect.left + 3, rect.bottom - 1), outlineColor); - AddLine(BPoint(rect.left + 3, rect.top + 1), - BPoint(rect.left + 7, rect.top + 5), outlineColor); - AddLine(BPoint(rect.left + 7, rect.top + 5), - BPoint(rect.left + 3, rect.bottom - 1), outlineColor); - - AddLine(BPoint(rect.left + 4, rect.top + 3), - BPoint(rect.left + 4, rect.bottom - 3), middleColor); - AddLine(BPoint(rect.left + 5, rect.top + 4), - BPoint(rect.left + 5, rect.bottom - 4), middleColor); - AddLine(BPoint(rect.left + 5, rect.top + 5), - BPoint(rect.left + 6, rect.top + 5), middleColor); - } else { - AddLine(BPoint(rect.right - 3, rect.top + 1), - BPoint(rect.right - 3, rect.bottom - 1), outlineColor); - AddLine(BPoint(rect.right - 3, rect.top + 1), - BPoint(rect.right - 7, rect.top + 5), outlineColor); - AddLine(BPoint(rect.right - 7, rect.top + 5), - BPoint(rect.right - 3, rect.bottom - 1), outlineColor); - - AddLine(BPoint(rect.right - 4, rect.top + 3), - BPoint(rect.right - 4, rect.bottom - 3), middleColor); - AddLine(BPoint(rect.right - 5, rect.top + 4), - BPoint(rect.right - 5, rect.bottom - 4), middleColor); - AddLine(BPoint(rect.right - 5, rect.top + 5), - BPoint(rect.right - 6, rect.top + 5), middleColor); - } - EndLineArray(); + arrowDirection = BControlLook::B_RIGHT_ARROW; break; case kPressed: - BeginLineArray(7); - if (fLeftAligned) { - AddLine(BPoint(rect.left + 1, rect.top + 7), - BPoint(rect.left + 7, rect.top + 7), outlineColor); - AddLine(BPoint(rect.left + 7, rect.top + 1), - BPoint(rect.left + 7, rect.top + 7), outlineColor); - AddLine(BPoint(rect.left + 1, rect.top + 7), - BPoint(rect.left + 7, rect.top + 1), outlineColor); - - AddLine(BPoint(rect.left + 3, rect.top + 6), - BPoint(rect.left + 6, rect.top + 6), middleColor); - AddLine(BPoint(rect.left + 4, rect.top + 5), - BPoint(rect.left + 6, rect.top + 5), middleColor); - AddLine(BPoint(rect.left + 5, rect.top + 4), - BPoint(rect.left + 6, rect.top + 4), middleColor); - AddLine(BPoint(rect.left + 6, rect.top + 3), - BPoint(rect.left + 6, rect.top + 4), middleColor); - } else { - AddLine(BPoint(rect.right - 1, rect.top + 7), - BPoint(rect.right - 7, rect.top + 7), outlineColor); - AddLine(BPoint(rect.right - 7, rect.top + 1), - BPoint(rect.right - 7, rect.top + 7), outlineColor); - AddLine(BPoint(rect.right - 1, rect.top + 7), - BPoint(rect.right - 7, rect.top + 1), outlineColor); - - AddLine(BPoint(rect.right - 3, rect.top + 6), - BPoint(rect.right - 6, rect.top + 6), middleColor); - AddLine(BPoint(rect.right - 4, rect.top + 5), - BPoint(rect.right - 6, rect.top + 5), middleColor); - AddLine(BPoint(rect.right - 5, rect.top + 4), - BPoint(rect.right - 6, rect.top + 4), middleColor); - AddLine(BPoint(rect.right - 6, rect.top + 3), - BPoint(rect.right - 6, rect.top + 4), middleColor); - } - EndLineArray(); + arrowDirection = BControlLook::B_RIGHT_DOWN_ARROW; break; case kExpanded: - BeginLineArray(6); - AddLine(BPoint(rect.left + 1, rect.top + 3), - BPoint(rect.right - 1, rect.top + 3), outlineColor); - AddLine(BPoint(rect.left + 1, rect.top + 3), - BPoint(rect.left + 5, rect.top + 7), outlineColor); - AddLine(BPoint(rect.left + 5, rect.top + 7), - BPoint(rect.right - 1, rect.top + 3), outlineColor); - - AddLine(BPoint(rect.left + 3, rect.top + 4), - BPoint(rect.right - 3, rect.top + 4), middleColor); - AddLine(BPoint(rect.left + 4, rect.top + 5), - BPoint(rect.right - 4, rect.top + 5), middleColor); - AddLine(BPoint(rect.left + 5, rect.top + 5), - BPoint(rect.left + 5, rect.top + 6), middleColor); - EndLineArray(); + arrowDirection = BControlLook::B_DOWN_ARROW; break; } + + SetDrawingMode(B_OP_COPY); + be_control_look->DrawArrowShape(this, rect, rect, arrowColor, + arrowDirection, 0, tint); } diff --git a/src/kits/tracker/FindPanel.cpp b/src/kits/tracker/FindPanel.cpp index 258f39bab3..6f92e7d1de 100644 --- a/src/kits/tracker/FindPanel.cpp +++ b/src/kits/tracker/FindPanel.cpp @@ -694,7 +694,7 @@ FindPanel::FindPanel(BRect frame, BFile* node, FindWindow* parent, BMessenger self(this); fRecentQueries = new BPopUpMenu("RecentQueries"); - FindPanel::AddRecentQueries(fRecentQueries, true, &self, + FindPanel::AddRecentQueries(fRecentQueries, true, &self, kSwitchToQueryTemplate); AddChild(new MiniMenuField(rect, "RecentQueries", fRecentQueries)); @@ -781,9 +781,10 @@ FindPanel::FindPanel(BRect frame, BFile* node, FindWindow* parent, rect = expandedBounds; rect.right = rect.left + 200; - rect.bottom = rect.top + 20;; + rect.bottom = rect.top + 20; fQueryName = new BTextControl(rect, "queryName", - B_TRANSLATE("Query name:"), "", 0); + B_TRANSLATE("Query name:"), "", B_FOLLOW_NONE, + B_NAVIGABLE | B_NAVIGABLE_JUMP); fQueryName->SetDivider(fQueryName->StringWidth(fQueryName->Label()) + 5); fMoreOptionsPane->AddItem(fQueryName, 1); FillCurrentQueryName(fQueryName, parent); @@ -1886,7 +1887,6 @@ FindPanel::AddRecentQueries(BMenu* menu, bool addSaveAsItem, for (int32 index = 0; index < count; index++) AddOneRecentItem(&recentQueries.ItemAt(index)->first, ¶ms); - if (addSaveAsItem) { // add a Save as template item if (count || templates.CountItems()) @@ -1894,7 +1894,7 @@ FindPanel::AddRecentQueries(BMenu* menu, bool addSaveAsItem, BMessage* message = new BMessage(kRunSaveAsTemplatePanel); BMenuItem* item = new BMenuItem( - B_TRANSLATE("Save Query as template"B_UTF8_ELLIPSIS), message); + B_TRANSLATE("Save Query as template" B_UTF8_ELLIPSIS), message); menu->AddItem(item); } } @@ -2420,7 +2420,8 @@ FindPanel::ShowOrHideMimeTypeMenu() TAttrView::TAttrView(BRect frame, int32 index) - : BView(frame, "AttrView", B_FOLLOW_NONE, B_WILL_DRAW) + : + BView(frame, "AttrView", B_FOLLOW_NONE, B_WILL_DRAW) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); @@ -3059,9 +3060,10 @@ DeleteTransientQueriesTask::StartUpTransientQueryCleaner() RecentFindItemsMenu::RecentFindItemsMenu(const char* title, const BMessenger* target, uint32 what) - : BMenu(title, B_ITEMS_IN_COLUMN), - fTarget(*target), - fWhat(what) + : + BMenu(title, B_ITEMS_IN_COLUMN), + fTarget(*target), + fWhat(what) { } @@ -3095,8 +3097,9 @@ TrackerBuildRecentFindItemsMenu(const char* title) DraggableQueryIcon::DraggableQueryIcon(BRect frame, const char* name, const BMessage* message, BMessenger messenger, uint32 resizeFlags, uint32 flags) - : DraggableIcon(frame, name, B_QUERY_MIMETYPE, B_LARGE_ICON, - message, messenger, resizeFlags, flags) + : + DraggableIcon(frame, name, B_QUERY_MIMETYPE, B_LARGE_ICON, + message, messenger, resizeFlags, flags) { } @@ -3329,4 +3332,3 @@ MostUsedNames::UpdateList() } } // namespace BPrivate - diff --git a/src/kits/tracker/FindPanel.h b/src/kits/tracker/FindPanel.h index bffffc1fc0..5bed25d1fd 100644 --- a/src/kits/tracker/FindPanel.h +++ b/src/kits/tracker/FindPanel.h @@ -223,7 +223,7 @@ class FindPanel : public BView { void AddMimeTypesToMenu(); // populates the type menu - static bool AddOneMimeTypeToMenu(const ShortMimeInfo*, void*); + static bool AddOneMimeTypeToMenu(const ShortMimeInfo*, void* castToMenu); void AddVolumes(BMenu*); // populates the volume menu diff --git a/src/kits/tracker/MiniMenuField.cpp b/src/kits/tracker/MiniMenuField.cpp index 27ac5181e7..782191849f 100644 --- a/src/kits/tracker/MiniMenuField.cpp +++ b/src/kits/tracker/MiniMenuField.cpp @@ -33,6 +33,8 @@ All rights reserved. */ +#include +#include #include #include @@ -96,10 +98,18 @@ void MiniMenuField::Draw(BRect) { BRect bounds(Bounds()); - bounds.InsetBy(2, 2); + bounds.OffsetBy(1, 2); + bounds.right--; + bounds.bottom -= 2; + if (IsFocus()) { + // draw the focus indicator border + SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); + StrokeRect(bounds); + } + bounds.right--; + bounds.bottom--; BRect rect(bounds); - rect.right--; - rect.bottom--; + rect.InsetBy(1, 1); rgb_color darkest = tint_color(kBlack, 0.6f); rgb_color dark = tint_color(kBlack, 0.4f); @@ -121,43 +131,17 @@ MiniMenuField::Draw(BRect) AddLine(rect.RightBottom(), rect.LeftBottom(), medium); AddLine(rect.LeftBottom(), rect.LeftTop(), light); AddLine(rect.LeftTop(), rect.RightTop(), light); - EndLineArray(); // draw triangle - rect = BRect(5, 5, 15, 15); - const rgb_color outlineColor = kBlack; - const rgb_color middleColor = {150, 150, 150, 255}; + rect = BRect(0, 0, 12, 12); + rect.OffsetBy(4, 4); + const rgb_color arrowColor = {150, 150, 150, 255}; + float tint = Window()->IsActive() ? B_DARKEN_3_TINT : B_DARKEN_1_TINT; - BeginLineArray(5); - AddLine(BPoint(rect.left + 3, rect.top + 1), - BPoint(rect.left + 3, rect.top + 7), outlineColor); - AddLine(BPoint(rect.left + 3, rect.top + 1), - BPoint(rect.left + 6, rect.top + 4), outlineColor); - AddLine(BPoint(rect.left + 6, rect.top + 4), - BPoint(rect.left + 3, rect.top + 7), outlineColor); - - AddLine(BPoint(rect.left + 4, rect.top + 3), - BPoint(rect.left + 4, rect.top + 5), middleColor); - AddLine(BPoint(rect.left + 5, rect.top + 4), - BPoint(rect.left + 5, rect.top + 4), middleColor); - EndLineArray(); - - // draw focus if focused, else erase focus - bounds = Bounds(); - bool focused = IsFocus() && Window()->IsActive(); - rgb_color markColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - rgb_color viewColor = ViewColor(); - BeginLineArray(4); - AddLine(BPoint(bounds.left, bounds.top), - BPoint(bounds.right, bounds.top), focused ? markColor : viewColor); - AddLine(BPoint(bounds.right, bounds.top), - BPoint(bounds.right, bounds.bottom), focused ? markColor : viewColor); - AddLine(BPoint(bounds.right, bounds.bottom), - BPoint(bounds.left, bounds.bottom), focused ? markColor : viewColor); - AddLine(BPoint(bounds.left, bounds.bottom), - BPoint(bounds.left, bounds.top), focused ? markColor : viewColor); - EndLineArray(); + SetDrawingMode(B_OP_COPY); + be_control_look->DrawArrowShape(this, rect, rect, arrowColor, + BControlLook::B_RIGHT_ARROW, 0, tint); } diff --git a/src/kits/tracker/PoseView.cpp b/src/kits/tracker/PoseView.cpp index cda2c0ee9a..6197cde882 100644 --- a/src/kits/tracker/PoseView.cpp +++ b/src/kits/tracker/PoseView.cpp @@ -10136,7 +10136,8 @@ BPoseView::ClearFilter() fLastFilterStringCount = 1; fLastFilterStringLength = 0; - fFiltering = false; + if (fRefFilter == NULL) + fFiltering = false; fFilteredPoseList->MakeEmpty(); Invalidate(); diff --git a/src/libs/termcap/termcap.src b/src/libs/termcap/termcap.src index ba69e28d67..1c08373176 100644 --- a/src/libs/termcap/termcap.src +++ b/src/libs/termcap/termcap.src @@ -6202,9 +6202,10 @@ xterm-24|vs100|xterms|xterm terminal emulator (X Window System):\ :u7=\E[6n:u8=\E[?1;2c:u9=\E[c:ue=\E[m:up=\E[A:us=\E[4m: # This is xterm for ncurses. +# Haiku: This one customized to declare 256 colors support xterm|xterm terminal emulator (X Window System):\ :5i:NP:am:bs:km:mi:ms:ut:xn:\ - :Co#8:co#80:it#8:li#24:pa#64:\ + :Co#256:co#80:it#8:li#24:pa#32767:\ :#2=\E[1;2H:#3=\E[2;2~:#4=\E[1;2D:%c=\E[6;2~:%e=\E[5;2~:\ :%i=\E[1;2C:*4=\E[3;2~:*7=\E[1;2F:@7=\EOF:@8=\EOM:\ :AB=\E[4%dm:AF=\E[3%dm:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:\ diff --git a/src/preferences/appearance/APRView.cpp b/src/preferences/appearance/APRView.cpp index 6b7c1e0873..2a4a21b8d8 100644 --- a/src/preferences/appearance/APRView.cpp +++ b/src/preferences/appearance/APRView.cpp @@ -1,10 +1,11 @@ /* - * Copyright 2002-2011, Haiku. All rights reserved. + * Copyright 2002-2013 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: - * DarkWyrm (darkwyrm@earthlink.net) - * Rene Gollent (rene@gollent.com) + * DarkWyrm, darkwyrm@earthlink.net + * Rene Gollent, rene@gollent.com + * John Scipione, jscipione@gmail.com */ @@ -78,7 +79,8 @@ APRView::APRView(const char* name) fScrollView = new BScrollView("ScrollView", fAttrList, 0, false, true); fScrollView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - for (int32 i = 0; i < color_description_count(); i++) { + int32 count = color_description_count(); + for (int32 i = 0; i < count; i++) { const ColorDescription& description = *get_color_description(i); const char* text = B_TRANSLATE_NOCOLLECT(description.text); color_which which = description.which; @@ -133,8 +135,8 @@ void APRView::MessageReceived(BMessage *msg) { if (msg->WasDropped()) { - rgb_color *color; - ssize_t size; + rgb_color* color = NULL; + ssize_t size = 0; if (msg->FindData("RGBColor", (type_code)'RGBC', (const void**)&color, &size) == B_OK) { @@ -152,11 +154,12 @@ APRView::MessageReceived(BMessage *msg) Window()->PostMessage(kMsgUpdate); break; } + case ATTRIBUTE_CHOSEN: { // Received when the user chooses a GUI fAttribute from the list - ColorWhichItem *item = (ColorWhichItem*) + ColorWhichItem* item = (ColorWhichItem*) fAttrList->ItemAt(fAttrList->CurrentSelection()); if (item == NULL) break; @@ -168,6 +171,7 @@ APRView::MessageReceived(BMessage *msg) Window()->PostMessage(kMsgUpdate); break; } + default: BView::MessageReceived(msg); break; @@ -178,7 +182,8 @@ APRView::MessageReceived(BMessage *msg) void APRView::LoadSettings() { - for (int32 i = 0; i < color_description_count(); i++) { + int32 count = color_description_count(); + for (int32 i = 0; i < count; i++) { color_which which = get_color_description(i)->which; fCurrentSet.SetColor(which, ui_color(which)); } @@ -192,9 +197,13 @@ APRView::SetDefaults() { fCurrentSet = ColorSet::DefaultColorSet(); - _UpdateControls(); _UpdateAllColors(); + rgb_color color = fCurrentSet.GetColor(fWhich); + fPicker->SetValue(color); + fColorPreview->SetColor(color); + fColorPreview->Invalidate(); + Window()->PostMessage(kMsgUpdate); } @@ -204,9 +213,13 @@ APRView::Revert() { fCurrentSet = fPrevSet; - _UpdateControls(); _UpdateAllColors(); + rgb_color color = fCurrentSet.GetColor(fWhich); + fPicker->SetValue(color); + fColorPreview->SetColor(color); + fColorPreview->Invalidate(); + Window()->PostMessage(kMsgUpdate); } @@ -214,11 +227,12 @@ APRView::Revert() bool APRView::IsDefaultable() { - for (int32 i = 0; i < color_description_count(); i++) { + for (int32 i = color_description_count() - 1; i >= 0; i--) { color_which which = get_color_description(i)->which; if (fCurrentSet.GetColor(which) != fDefaultSet.GetColor(which)) return true; } + return false; } @@ -226,11 +240,12 @@ APRView::IsDefaultable() bool APRView::IsRevertable() { - for (int32 i = 0; i < color_description_count(); i++) { + for (int32 i = color_description_count() - 1; i >= 0; i--) { color_which which = get_color_description(i)->which; if (fCurrentSet.GetColor(which) != fPrevSet.GetColor(which)) return true; } + return false; } @@ -240,17 +255,9 @@ APRView::_SetCurrentColor(rgb_color color) { fCurrentSet.SetColor(fWhich, color); set_ui_color(fWhich, color); - _UpdateControls(); -} - - -void -APRView::_UpdateControls() -{ - rgb_color color = fCurrentSet.GetColor(fWhich); int32 currentIndex = fAttrList->CurrentSelection(); - ColorWhichItem *item = (ColorWhichItem*) fAttrList->ItemAt(currentIndex); + ColorWhichItem* item = (ColorWhichItem*)fAttrList->ItemAt(currentIndex); if (item != NULL) { item->SetColor(color); fAttrList->InvalidateItem(currentIndex); @@ -265,9 +272,11 @@ APRView::_UpdateControls() void APRView::_UpdateAllColors() { - for (int32 i = 0; i < color_description_count(); i++) { + for (int32 i = color_description_count() - 1; i >= 0; i--) { color_which which = get_color_description(i)->which; rgb_color color = fCurrentSet.GetColor(which); set_ui_color(which, color); + static_cast(fAttrList->ItemAt(i))->SetColor(color); + fAttrList->InvalidateItem(i); } } diff --git a/src/preferences/appearance/APRView.h b/src/preferences/appearance/APRView.h index 41b65cd54d..6f1317850a 100644 --- a/src/preferences/appearance/APRView.h +++ b/src/preferences/appearance/APRView.h @@ -52,7 +52,6 @@ public: private: void _SetCurrentColor(rgb_color color); - void _UpdateControls(); void _UpdateAllColors(); private: diff --git a/src/preferences/appearance/APRWindow.cpp b/src/preferences/appearance/APRWindow.cpp index 15ab77e906..661f998400 100644 --- a/src/preferences/appearance/APRWindow.cpp +++ b/src/preferences/appearance/APRWindow.cpp @@ -99,10 +99,10 @@ APRWindow::MessageReceived(BMessage *message) break; case kMsgRevert: - fColorsView->Revert(); - fAntialiasingSettings->Revert(); - fLookAndFeelSettings->Revert(); fFontSettings->Revert(); + fColorsView->Revert(); + fLookAndFeelSettings->Revert(); + fAntialiasingSettings->Revert(); _UpdateButtons(); break; diff --git a/src/preferences/appearance/ColorSet.cpp b/src/preferences/appearance/ColorSet.cpp index 819543769d..1260aeba38 100644 --- a/src/preferences/appearance/ColorSet.cpp +++ b/src/preferences/appearance/ColorSet.cpp @@ -8,6 +8,7 @@ * Rene Gollent */ + #include #include #include @@ -21,11 +22,12 @@ #include #include "ColorSet.h" + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "Colors tab" -static ColorDescription sColorDescriptionTable[] = -{ + +static ColorDescription sColorDescriptionTable[] = { { B_PANEL_BACKGROUND_COLOR, B_TRANSLATE_MARK("Panel background") }, { B_PANEL_TEXT_COLOR, B_TRANSLATE_MARK("Panel text") }, { B_DOCUMENT_BACKGROUND_COLOR, B_TRANSLATE_MARK("Document background") }, @@ -53,6 +55,8 @@ static ColorDescription sColorDescriptionTable[] = { B_LIST_ITEM_TEXT_COLOR, B_TRANSLATE_MARK("List item text") }, { B_LIST_SELECTED_ITEM_TEXT_COLOR, B_TRANSLATE_MARK("Selected list item text") }, + { B_SCROLL_BAR_THUMB_COLOR, + B_TRANSLATE_MARK("Scroll bar thumb") }, { B_TOOL_TIP_BACKGROUND_COLOR, B_TRANSLATE_MARK("Tooltip background") }, { B_TOOL_TIP_TEXT_COLOR, B_TRANSLATE_MARK("Tooltip text") }, { B_SUCCESS_COLOR, B_TRANSLATE_MARK("Success") }, @@ -70,6 +74,7 @@ static ColorDescription sColorDescriptionTable[] = const int32 sColorDescriptionCount = sizeof(sColorDescriptionTable) / sizeof(ColorDescription); + const ColorDescription* get_color_description(int32 index) { @@ -78,12 +83,14 @@ get_color_description(int32 index) return &sColorDescriptionTable[index]; } + int32 color_description_count(void) { return sColorDescriptionCount; } + // #pragma mark - @@ -91,6 +98,7 @@ ColorSet::ColorSet() { } + /*! \brief Copy constructor which does a massive number of assignments \param cs Color set to copy from @@ -100,12 +108,14 @@ ColorSet::ColorSet(const ColorSet &cs) *this = cs; } + /*! - \brief Overloaded assignment operator which does a massive number of assignments + \brief Overloaded assignment operator which does a massive number of + assignments. \param cs Color set to copy from \return The new values assigned to the color set */ -ColorSet & +ColorSet& ColorSet::operator=(const ColorSet &cs) { fColors = cs.fColors; @@ -121,7 +131,7 @@ ColorSet ColorSet::DefaultColorSet(void) { ColorSet set; - + for (int i = 0; i < sColorDescriptionCount; i++) { color_which which = get_color_description(i)->which; set.fColors[which] = @@ -148,5 +158,3 @@ ColorSet::GetColor(int32 which) { return fColors[(color_which)which]; } - - diff --git a/src/preferences/appearance/ColorSet.h b/src/preferences/appearance/ColorSet.h index e260f480ad..d65590a8e6 100644 --- a/src/preferences/appearance/ColorSet.h +++ b/src/preferences/appearance/ColorSet.h @@ -17,12 +17,13 @@ #include -typedef struct -{ - color_which which; - const char* text; + +typedef struct { + color_which which; + const char* text; } ColorDescription; + const ColorDescription* get_color_description(int32 index); int32 color_description_count(void); @@ -39,9 +40,9 @@ class ColorSet : public BLocker { rgb_color GetColor(int32 which); void SetColor(color_which which, rgb_color value); - + static ColorSet DefaultColorSet(void); - + inline bool operator==(const ColorSet &other) { return fColors == other.fColors; @@ -56,4 +57,5 @@ class ColorSet : public BLocker { std::map fColors; }; + #endif // COLOR_SET_H diff --git a/src/preferences/appearance/ColorWhichItem.cpp b/src/preferences/appearance/ColorWhichItem.cpp index e9fa522fa2..f380228e71 100644 --- a/src/preferences/appearance/ColorWhichItem.cpp +++ b/src/preferences/appearance/ColorWhichItem.cpp @@ -1,11 +1,11 @@ /* - * Copyright 2002-2008, Haiku. All rights reserved. + * Copyright 2002-2013 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: - * DarkWyrm (darkwyrm@earthlink.net) - * Rene Gollent (rene@gollent.com) - * Ryan Leavengood + * DarkWyrm, darkwyrm@earthlink.net + * Rene Gollent, rene@gollent.com + * Ryan Leavengood, leavengood@gmail.com */ @@ -25,7 +25,7 @@ ColorWhichItem::ColorWhichItem(const char* text, color_which which, void -ColorWhichItem::DrawItem(BView *owner, BRect frame, bool complete) +ColorWhichItem::DrawItem(BView* owner, BRect frame, bool complete) { rgb_color highColor = owner->HighColor(); rgb_color lowColor = owner->LowColor(); @@ -85,4 +85,3 @@ ColorWhichItem::SetColor(rgb_color color) { fColor = color; } - diff --git a/src/preferences/appearance/ColorWhichItem.h b/src/preferences/appearance/ColorWhichItem.h index abc5853719..09c5db3550 100644 --- a/src/preferences/appearance/ColorWhichItem.h +++ b/src/preferences/appearance/ColorWhichItem.h @@ -3,31 +3,34 @@ * Distributed under the terms of the MIT License. * * Authors: - * DarkWyrm - * Rene Gollent (rene@gollent.com) - * Ryan Leavengood + * DarkWyrm, bpmagic@columbus.rr.com + * Rene Gollent, rene@gollent.com + * Ryan Leavengood, leavengood@gmail.com + * John Scipione, jscipione@gmail.com */ - - #ifndef COLORWHICH_ITEM_H #define COLORWHICH_ITEM_H + #include #include #include + class ColorWhichItem : public BStringItem { public: - ColorWhichItem(const char* text, color_which which, rgb_color color); + ColorWhichItem(const char* text, color_which which, + rgb_color color); - virtual void DrawItem(BView *owner, BRect frame, bool complete); - color_which ColorWhich(void); - void SetColor(rgb_color color); + virtual void DrawItem(BView* owner, BRect frame, bool complete); + color_which ColorWhich(void); + void SetColor(rgb_color color); private: - color_which fColorWhich; - rgb_color fColor; + color_which fColorWhich; + rgb_color fColor; }; + #endif diff --git a/src/preferences/backgrounds/BackgroundImage.cpp b/src/preferences/backgrounds/BackgroundImage.cpp index 9c55d8cb4c..f5c94892dc 100644 --- a/src/preferences/backgrounds/BackgroundImage.cpp +++ b/src/preferences/backgrounds/BackgroundImage.cpp @@ -283,7 +283,7 @@ BackgroundImage::Show(BackgroundImageInfo* info, BView* view) offset.x *= x_ratio; offset.y *= y_ratio; - uint32 tile = 0; + uint32 options = 0; uint32 followFlags = B_FOLLOW_TOP | B_FOLLOW_LEFT; // figure out the display mode and the destination bounds for the bitmap @@ -312,6 +312,7 @@ BackgroundImage::Show(BackgroundImageInfo* info, BView* view) viewBounds.Width(), viewBounds.Height() + overlap); } followFlags = B_FOLLOW_ALL; + options |= B_FILTER_BITMAP_BILINEAR; break; } // else fall thru @@ -328,13 +329,13 @@ BackgroundImage::Show(BackgroundImageInfo* info, BView* view) (viewBounds.Width() - destinationBitmapBounds.Width()) / 2, (viewBounds.Height() - destinationBitmapBounds.Height()) / 2); //} - tile = B_TILE_BITMAP; + options |= B_TILE_BITMAP; break; } // switch to the bitmap and force a redraw view->SetViewBitmap(bitmap, bitmapBounds, destinationBitmapBounds, - followFlags, tile); + followFlags, options); view->Invalidate(); /*if (fShowingBitmap != info) { diff --git a/src/preferences/network/EthernetSettingsView.cpp b/src/preferences/network/EthernetSettingsView.cpp index 95e193eb60..08b41c7fa3 100644 --- a/src/preferences/network/EthernetSettingsView.cpp +++ b/src/preferences/network/EthernetSettingsView.cpp @@ -98,7 +98,6 @@ EthernetSettingsView::EthernetSettingsView() { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - fSocket = socket(AF_INET, SOCK_DGRAM, 0); _GatherInterfaces(); // build the GUI @@ -216,7 +215,6 @@ EthernetSettingsView::EthernetSettingsView() EthernetSettingsView::~EthernetSettingsView() { - close(fSocket); } diff --git a/src/preferences/network/EthernetSettingsView.h b/src/preferences/network/EthernetSettingsView.h index 24fd31fee2..452ed3908a 100644 --- a/src/preferences/network/EthernetSettingsView.h +++ b/src/preferences/network/EthernetSettingsView.h @@ -79,7 +79,6 @@ private: Settings* fCurrentSettings; int32 fStatus; - int fSocket; }; #endif /* ETHERNET_SETTINGS_VIEW_H */ diff --git a/src/servers/app/ClientMemoryAllocator.cpp b/src/servers/app/ClientMemoryAllocator.cpp index 8f3001d992..f9ec018f31 100644 --- a/src/servers/app/ClientMemoryAllocator.cpp +++ b/src/servers/app/ClientMemoryAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2012, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2013, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -66,6 +66,10 @@ ClientMemoryAllocator::~ClientMemoryAllocator() void* ClientMemoryAllocator::Allocate(size_t size, block** _address, bool& newArea) { + // A detached allocator no longer allows any further allocations + if (fApplication == NULL) + return NULL; + BAutolock locker(fLock); // Search best matching free block from the list @@ -179,18 +183,30 @@ ClientMemoryAllocator::Free(block* freeBlock) fChunks.Remove(chunk); delete_area(chunk->area); - fApplication->NotifyDeleteClientArea(chunk->area); + + if (fApplication != NULL) + fApplication->NotifyDeleteClientArea(chunk->area); free(chunk); } } +void +ClientMemoryAllocator::Detach() +{ + BAutolock locker(fLock); + fApplication = NULL; +} + + void ClientMemoryAllocator::Dump() { - debug_printf("Application %" B_PRId32 ", %s: chunks:\n", - fApplication->ClientTeam(), fApplication->Signature()); + if (fApplication != NULL) { + debug_printf("Application %" B_PRId32 ", %s: chunks:\n", + fApplication->ClientTeam(), fApplication->Signature()); + } chunk_list::Iterator iterator = fChunks.GetIterator(); int32 i = 0; diff --git a/src/servers/app/ClientMemoryAllocator.h b/src/servers/app/ClientMemoryAllocator.h index 7af6f3a0ef..05ab8df533 100644 --- a/src/servers/app/ClientMemoryAllocator.h +++ b/src/servers/app/ClientMemoryAllocator.h @@ -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: @@ -43,6 +43,8 @@ public: bool& newArea); void Free(block* cookie); + void Detach(); + void Dump(); private: diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index f5660b914b..d6895b4657 100644 --- a/src/servers/app/DesktopSettings.cpp +++ b/src/servers/app/DesktopSettings.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include "Desktop.h" @@ -77,7 +78,7 @@ DesktopSettingsPrivate::_SetDefaults() fWorkspacesRows = 2; memcpy(fShared.colors, BPrivate::kDefaultColors, - sizeof(rgb_color) * kNumColors); + sizeof(rgb_color) * kColorWhichCount); gSubpixelAntialiasing = false; gDefaultHintingMode = HINTING_MODE_ON; @@ -291,7 +292,7 @@ DesktopSettingsPrivate::_Load() } // colors - for (int32 i = 0; i < kNumColors; i++) { + for (int32 i = 0; i < kColorWhichCount; i++) { char colorName[12]; snprintf(colorName, sizeof(colorName), "color%" B_PRId32, (int32)index_to_color_which(i)); @@ -436,7 +437,7 @@ DesktopSettingsPrivate::Save(uint32 mask) settings.AddInt8("subpixel average weight", gSubpixelAverageWeight); settings.AddBool("subpixel ordering", gSubpixelOrderingRGB); - for (int32 i = 0; i < kNumColors; i++) { + for (int32 i = 0; i < kColorWhichCount; i++) { char colorName[12]; snprintf(colorName, sizeof(colorName), "color%" B_PRId32, (int32)index_to_color_which(i)); @@ -648,15 +649,16 @@ DesktopSettingsPrivate::WorkspacesMessage(int32 index) const void DesktopSettingsPrivate::SetUIColor(color_which which, const rgb_color color) { - // int32 index = color_which_to_index(which); - if (index < 0 || index >= kNumColors) + if (index < 0 || index >= kColorWhichCount) return; + fShared.colors[index] = color; // TODO: deprecate the background_color member of the menu_info struct, // otherwise we have to keep this duplication... if (which == B_MENU_BACKGROUND_COLOR) fMenuInfo.background_color = color; + Save(kAppearanceSettings); } @@ -666,8 +668,9 @@ DesktopSettingsPrivate::UIColor(color_which which) const { static const rgb_color invalidColor = {0, 0, 0, 0}; int32 index = color_which_to_index(which); - if (index < 0 || index >= kNumColors) + if (index < 0 || index >= kColorWhichCount) return invalidColor; + return fShared.colors[index]; } diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 90651ea40d..057df07912 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2012, Haiku. + * Copyright 2001-2013, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -192,6 +192,7 @@ ServerApp::~ServerApp() fWindowListLock.Lock(); } + fMemoryAllocator.Detach(); fMapLocker.Lock(); while (!fBitmapMap.empty()) diff --git a/src/servers/net/AutoconfigLooper.cpp b/src/servers/net/AutoconfigLooper.cpp index 85bf5a88b0..bd11a2f589 100644 --- a/src/servers/net/AutoconfigLooper.cpp +++ b/src/servers/net/AutoconfigLooper.cpp @@ -33,7 +33,8 @@ AutoconfigLooper::AutoconfigLooper(BMessenger target, const char* device) fTarget(target), fDevice(device), fCurrentClient(NULL), - fLastMediaStatus(0) + fLastMediaStatus(0), + fJoiningNetwork(false) { BMessage ready(kMsgReadyToRun); PostMessage(&ready); @@ -124,9 +125,85 @@ AutoconfigLooper::_ConfigureIPv4() void AutoconfigLooper::_ReadyToRun() { - start_watching_network(B_WATCH_NETWORK_LINK_CHANGES, this); - _ConfigureIPv4(); - //_ConfigureIPv6(); // TODO: router advertisement and dhcpv6 + start_watching_network( + B_WATCH_NETWORK_LINK_CHANGES | B_WATCH_NETWORK_WLAN_CHANGES, this); + + BNetworkInterface interface(fDevice.String()); + if (interface.HasLink()) { + _ConfigureIPv4(); + //_ConfigureIPv6(); // TODO: router advertisement and dhcpv6 + + // Also make sure we don't spuriously try to configure again from + // a link changed notification that might race us. + fLastMediaStatus |= IFM_ACTIVE; + } +} + + +void +AutoconfigLooper::_NetworkMonitorNotification(BMessage* message) +{ + int32 opcode; + BString device; + if (message->FindString("device", &device) != B_OK) { + if (message->FindString("interface", &device) != B_OK) + return; + + // TODO: Clean this mess up. Wireless devices currently use their + // "device_name" in the interface field. First of all the + // joins/leaves/scans should be device, not interface specific, so + // the field should be changed. Then the device_name as seen by the + // driver is missing the "/dev" part, as it is a relative path within + // "/dev". On the other hand the net stack uses names that include + // "/dev" as it uses them to open the fds, hence a full absolute path. + // Note that the wpa_supplicant does the same workaround as we do here + // to build an interface name, so that has to be changed as well when + // this is fixed. + device.Prepend("/dev/"); + } + + if (device != fDevice || message->FindInt32("opcode", &opcode) != B_OK) + return; + + switch (opcode) { + case B_NETWORK_DEVICE_LINK_CHANGED: + { + int32 media; + if (message->FindInt32("media", &media) != B_OK) + break; + + if ((fLastMediaStatus & IFM_ACTIVE) == 0 + && (media & IFM_ACTIVE) != 0) { + // Reconfigure the interface when we have a link again + _ConfigureIPv4(); + //_ConfigureIPv6(); // TODO: router advertisement and dhcpv6 + } + + fLastMediaStatus = media; + break; + } + + case B_NETWORK_WLAN_SCANNED: + { + if (fJoiningNetwork || (fLastMediaStatus & IFM_ACTIVE) != 0) { + // We already have a link or are already joining. + break; + } + + fJoiningNetwork = true; + // TODO: For now we never reset this flag. We can only do that + // after infrastructure has been added to discern a scan reason. + // If we would always auto join we would possibly interfere + // with active scans in the process of connecting to an AP + // either for the initial connection, or after connection loss + // to re-establish the link. + + BMessage message(kMsgAutoJoinNetwork); + message.AddString("device", fDevice); + fTarget.SendMessage(&message); + break; + } + } } @@ -139,23 +216,7 @@ AutoconfigLooper::MessageReceived(BMessage* message) break; case B_NETWORK_MONITOR: - const char* device; - int32 opcode; - int32 media; - if (message->FindInt32("opcode", &opcode) != B_OK - || opcode != B_NETWORK_DEVICE_LINK_CHANGED - || message->FindString("device", &device) != B_OK - || fDevice != device - || message->FindInt32("media", &media) != B_OK) - break; - - if ((fLastMediaStatus & IFM_ACTIVE) == 0 - && (media & IFM_ACTIVE) != 0) { - // Reconfigure the interface when we have a link again - _ConfigureIPv4(); - //_ConfigureIPv6(); // TODO: router advertisement and dhcpv6 - } - fLastMediaStatus = media; + _NetworkMonitorNotification(message); break; default: diff --git a/src/servers/net/AutoconfigLooper.h b/src/servers/net/AutoconfigLooper.h index fef9c2f95c..4ec5a5427f 100644 --- a/src/servers/net/AutoconfigLooper.h +++ b/src/servers/net/AutoconfigLooper.h @@ -30,11 +30,13 @@ private: void _RemoveClient(); void _ConfigureIPv4(); void _ReadyToRun(); + void _NetworkMonitorNotification(BMessage* message); BMessenger fTarget; BString fDevice; AutoconfigClient* fCurrentClient; int32 fLastMediaStatus; + bool fJoiningNetwork; }; #endif // AUTOCONFIG_LOOPER_H diff --git a/src/servers/net/NetServer.cpp b/src/servers/net/NetServer.cpp index e24e70dada..da8472cc72 100644 --- a/src/servers/net/NetServer.cpp +++ b/src/servers/net/NetServer.cpp @@ -88,7 +88,7 @@ private: void _StartServices(); status_t _HandleDeviceMonitor(BMessage* message); - status_t _AutoJoinNetwork(const char* name); + status_t _AutoJoinNetwork(const BMessage& message); status_t _JoinNetwork(const BMessage& message, const char* name = NULL); status_t _LeaveNetwork(const BMessage& message); @@ -321,6 +321,12 @@ NetServer::MessageReceived(BMessage* message) break; } + case kMsgAutoJoinNetwork: + { + _AutoJoinNetwork(*message); + break; + } + case kMsgCountPersistentNetworks: { BMessage reply(B_REPLY); @@ -532,26 +538,6 @@ NetServer::_ConfigureInterface(BMessage& message) } } - BNetworkDevice device(name); - if (device.IsWireless() && !device.HasLink()) { - const char* networkName; - if (message.FindString("network", &networkName) == B_OK) { - // join configured network - status_t status = _JoinNetwork(message, networkName); - if (status != B_OK) { - fprintf(stderr, "%s: joining network \"%s\" failed: %s\n", - interface.Name(), networkName, strerror(status)); - } - } else { - // auto select network to join - status_t status = _AutoJoinNetwork(name); - if (status != B_OK) { - fprintf(stderr, "%s: auto joining network failed: %s\n", - interface.Name(), strerror(status)); - } - } - } - // Set up IPv6 Link Local address (based on MAC, if not loopback) _ConfigureIPv6LinkLocal(name); @@ -671,6 +657,19 @@ NetServer::_ConfigureInterface(BMessage& message) } } + const char* networkName; + if (message.FindString("network", &networkName) == B_OK) { + // We want to join a specific network. + BNetworkDevice device(name); + if (device.IsWireless() && !device.HasLink()) { + status_t status = _JoinNetwork(message, networkName); + if (status != B_OK) { + fprintf(stderr, "%s: joining network \"%s\" failed: %s\n", + interface.Name(), networkName, strerror(status)); + } + } + } + if (startAutoConfig) { // start auto configuration AutoconfigLooper* looper = new AutoconfigLooper(this, name); @@ -972,8 +971,8 @@ NetServer::_HandleDeviceMonitor(BMessage* message) || message->FindString("path", &path) != B_OK) return B_BAD_VALUE; - if (strncmp(path, "/dev/net", 9)) { - // not a device entry, ignore + if (strncmp(path, "/dev/net/", 9)) { + // not a valid device entry, ignore return B_NAME_NOT_FOUND; } @@ -987,12 +986,13 @@ NetServer::_HandleDeviceMonitor(BMessage* message) status_t -NetServer::_AutoJoinNetwork(const char* name) +NetServer::_AutoJoinNetwork(const BMessage& message) { - BNetworkDevice device(name); + const char* name = NULL; + if (message.FindString("device", &name) != B_OK) + return B_BAD_VALUE; - BMessage message; - message.AddString("device", name); + BNetworkDevice device(name); // Choose among configured networks diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp index b6f18d47f4..b41cc7154d 100644 --- a/src/system/kernel/arch/arm/arch_int.cpp +++ b/src/system/kernel/arch/arm/arch_int.cpp @@ -277,7 +277,7 @@ arch_arm_data_abort(struct iframe *frame) enable_interrupts(); - vm_page_fault(far, frame->pc, isWrite, isUser, &newip); + vm_page_fault(far, frame->pc, isWrite, false, isUser, &newip); if (newip != 0) { // the page fault handler wants us to modify the iframe to set the diff --git a/src/system/kernel/arch/m68k/arch_int.cpp b/src/system/kernel/arch/m68k/arch_int.cpp index a982a75e8a..b80942ac66 100644 --- a/src/system/kernel/arch/m68k/arch_int.cpp +++ b/src/system/kernel/arch/m68k/arch_int.cpp @@ -238,6 +238,7 @@ m68k_exception_entry(struct iframe *iframe) vm_page_fault(fault_address(iframe), iframe->cpu.pc, fault_was_write(iframe), // store or load + false, iframe->cpu.sr & SR_S, // was the system in user or supervisor &newip); if (newip != 0) { diff --git a/src/system/kernel/arch/ppc/arch_int.cpp b/src/system/kernel/arch/ppc/arch_int.cpp index 61ede968ef..ac1c60b284 100644 --- a/src/system/kernel/arch/ppc/arch_int.cpp +++ b/src/system/kernel/arch/ppc/arch_int.cpp @@ -164,6 +164,7 @@ ppc_exception_entry(int vector, struct iframe *iframe) vm_page_fault(iframe->dar, iframe->srr0, iframe->dsisr & (1 << 25), // store or load + false, iframe->srr1 & (1 << 14), // was the system in user or supervisor &newip); if (newip != 0) { diff --git a/src/system/kernel/arch/x86/32/arch.S b/src/system/kernel/arch/x86/32/arch.S index 97eb069a40..90ef56b363 100644 --- a/src/system/kernel/arch/x86/32/arch.S +++ b/src/system/kernel/arch/x86/32/arch.S @@ -115,7 +115,7 @@ FUNCTION(x86_swap_pgdir): ret FUNCTION_END(x86_swap_pgdir) -/* thread exit stub - is copied to the userspace stack in arch_thread_enter_uspace() */ +/* thread exit stub */ .align 4 FUNCTION(x86_userspace_thread_exit): pushl %eax diff --git a/src/system/kernel/arch/x86/32/interrupts.S b/src/system/kernel/arch/x86/32/interrupts.S index 5fde6b901e..912c583cb9 100644 --- a/src/system/kernel/arch/x86/32/interrupts.S +++ b/src/system/kernel/arch/x86/32/interrupts.S @@ -766,7 +766,9 @@ FUNCTION(x86_sysenter): pushl $USER_CODE_SEG // user cs // user_eip - movl USER_COMMPAGE_ADDR + 4 * COMMPAGE_ENTRY_X86_SYSCALL, %edx + movl THREAD_team(%edx), %edx + movl TEAM_commpage_address(%edx), %edx + addl 4 * COMMPAGE_ENTRY_X86_SYSCALL(%edx), %edx addl $4, %edx // sysenter is at offset 2, 2 bytes long pushl %edx diff --git a/src/system/kernel/arch/x86/32/signals.cpp b/src/system/kernel/arch/x86/32/signals.cpp index 80977a331c..fe3913f95e 100644 --- a/src/system/kernel/arch/x86/32/signals.cpp +++ b/src/system/kernel/arch/x86/32/signals.cpp @@ -89,14 +89,13 @@ register_signal_handler_function(const char* functionName, int32 commpageIndex, ASSERT(expectedAddress == symbolInfo.address); // fill in the commpage table entry - fill_commpage_entry(commpageIndex, (void*)symbolInfo.address, - symbolInfo.size); + addr_t position = fill_commpage_entry(commpageIndex, + (void*)symbolInfo.address, symbolInfo.size); // add symbol to the commpage image image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, commpageSymbolName, - ((addr_t*)USER_COMMPAGE_ADDR)[commpageIndex], symbolInfo.size, - B_SYMBOL_TYPE_TEXT); + elf_add_memory_image_symbol(image, commpageSymbolName, position, + symbolInfo.size, B_SYMBOL_TYPE_TEXT); } @@ -116,10 +115,10 @@ x86_initialize_commpage_signal_handler() addr_t -x86_get_user_signal_handler_wrapper(bool beosHandler) +x86_get_user_signal_handler_wrapper(bool beosHandler, void* commPageAdddress) { int32 index = beosHandler ? COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS : COMMPAGE_ENTRY_X86_SIGNAL_HANDLER; - return ((addr_t*)USER_COMMPAGE_ADDR)[index]; + return ((addr_t*)commPageAdddress)[index] + (addr_t)commPageAdddress; } diff --git a/src/system/kernel/arch/x86/32/signals_asm.S b/src/system/kernel/arch/x86/32/signals_asm.S index 38c32e9d54..2618d17481 100644 --- a/src/system/kernel/arch/x86/32/signals_asm.S +++ b/src/system/kernel/arch/x86/32/signals_asm.S @@ -37,7 +37,8 @@ FUNCTION(x86_signal_frame_function_beos): lea SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%esi), %eax push %eax push %edi - movl USER_COMMPAGE_ADDR + 4 * COMMPAGE_ENTRY_X86_MEMCPY, %eax + movl SIGNAL_FRAME_DATA_commpage_address(%esi), %eax + addl 4 * COMMPAGE_ENTRY_X86_MEMCPY(%eax), %eax call *%eax addl $12, %esp @@ -57,7 +58,8 @@ FUNCTION(x86_signal_frame_function_beos): push %edi lea SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%esi), %eax push %eax - movl USER_COMMPAGE_ADDR + 4 * COMMPAGE_ENTRY_X86_MEMCPY, %eax + movl SIGNAL_FRAME_DATA_commpage_address(%esi), %eax + addl 4 * COMMPAGE_ENTRY_X86_MEMCPY(%eax), %eax call *%eax addl $12 + VREGS_sizeof, %esp diff --git a/src/system/kernel/arch/x86/32/syscalls.cpp b/src/system/kernel/arch/x86/32/syscalls.cpp index f0c9b7c1a0..5b007e61e1 100644 --- a/src/system/kernel/arch/x86/32/syscalls.cpp +++ b/src/system/kernel/arch/x86/32/syscalls.cpp @@ -106,11 +106,11 @@ x86_initialize_syscall(void) // fill in the table entry size_t len = (size_t)((addr_t)syscallCodeEnd - (addr_t)syscallCode); - fill_commpage_entry(COMMPAGE_ENTRY_X86_SYSCALL, syscallCode, len); + addr_t position = fill_commpage_entry(COMMPAGE_ENTRY_X86_SYSCALL, + syscallCode, len); // add syscall to the commpage image image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, "commpage_syscall", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SYSCALL], len, + elf_add_memory_image_symbol(image, "commpage_syscall", position, len, B_SYMBOL_TYPE_TEXT); } diff --git a/src/system/kernel/arch/x86/32/thread.cpp b/src/system/kernel/arch/x86/32/thread.cpp index 5878aacced..66465c2951 100644 --- a/src/system/kernel/arch/x86/32/thread.cpp +++ b/src/system/kernel/arch/x86/32/thread.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include #include @@ -200,6 +202,15 @@ arch_thread_dump_info(void *info) } +static addr_t +arch_randomize_stack_pointer(addr_t value) +{ + STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1); + value -= random_value() & (B_PAGE_SIZE - 1); + return value & ~addr_t(0xf); +} + + /*! Sets up initial thread context and enters user space */ status_t @@ -207,21 +218,19 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, void* args2) { addr_t stackTop = thread->user_stack_base + thread->user_stack_size; - uint32 codeSize = (addr_t)x86_end_userspace_thread_exit - - (addr_t)x86_userspace_thread_exit; uint32 args[3]; TRACE(("arch_thread_enter_userspace: entry 0x%lx, args %p %p, " "ustack_top 0x%lx\n", entry, args1, args2, stackTop)); - // copy the little stub that calls exit_thread() when the thread entry - // function returns, as well as the arguments of the entry function - stackTop -= codeSize; + stackTop = arch_randomize_stack_pointer(stackTop); - if (user_memcpy((void *)stackTop, (const void *)&x86_userspace_thread_exit, codeSize) < B_OK) - return B_BAD_ADDRESS; - - args[0] = stackTop; + // Copy the address of the stub that calls exit_thread() when the thread + // entry function returns to the top of the stack to act as the return + // address. The stub is inside commpage. + addr_t commPageAddress = (addr_t)thread->team->commpage_address; + args[0] = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT] + + commPageAddress; args[1] = (uint32)args1; args[2] = (uint32)args2; stackTop -= sizeof(args); @@ -345,7 +354,8 @@ arch_setup_signal_frame(Thread* thread, struct sigaction* action, // the prepared stack, executing the signal handler wrapper function. frame->user_sp = (addr_t)userStack; frame->ip = x86_get_user_signal_handler_wrapper( - (action->sa_flags & SA_BEOS_COMPATIBLE_HANDLER) != 0); + (action->sa_flags & SA_BEOS_COMPATIBLE_HANDLER) != 0, + thread->team->commpage_address); return B_OK; } diff --git a/src/system/kernel/arch/x86/64/arch.S b/src/system/kernel/arch/x86/64/arch.S index cbaeec86cd..3f07b957d2 100644 --- a/src/system/kernel/arch/x86/64/arch.S +++ b/src/system/kernel/arch/x86/64/arch.S @@ -118,7 +118,7 @@ FUNCTION(x86_swap_pgdir): FUNCTION_END(x86_swap_pgdir) -/* thread exit stub - copied to the userspace stack in arch_thread_enter_uspace() */ +/* thread exit stub */ .align 8 FUNCTION(x86_userspace_thread_exit): movq %rax, %rdi diff --git a/src/system/kernel/arch/x86/64/signals.cpp b/src/system/kernel/arch/x86/64/signals.cpp index 947e76fbb7..06d41ac6b2 100644 --- a/src/system/kernel/arch/x86/64/signals.cpp +++ b/src/system/kernel/arch/x86/64/signals.cpp @@ -28,12 +28,12 @@ x86_initialize_commpage_signal_handler() // Copy the signal handler code to the commpage. size_t len = (size_t)((addr_t)handlerCodeEnd - (addr_t)handlerCode); - fill_commpage_entry(COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, handlerCode, len); + addr_t position = fill_commpage_entry(COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, + handlerCode, len); // Add symbol to the commpage image. image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, "commpage_signal_handler", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER], + elf_add_memory_image_symbol(image, "commpage_signal_handler", position, len, B_SYMBOL_TYPE_TEXT); } diff --git a/src/system/kernel/arch/x86/64/syscalls.cpp b/src/system/kernel/arch/x86/64/syscalls.cpp index 20bf44ef4e..4407498aa2 100644 --- a/src/system/kernel/arch/x86/64/syscalls.cpp +++ b/src/system/kernel/arch/x86/64/syscalls.cpp @@ -20,7 +20,8 @@ static void init_syscall_registers(void* dummy, int cpuNum) { // Enable SYSCALL (EFER.SCE = 1). - x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) | (1 << 0)); + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) + | IA32_MSR_EFER_SYSCALL); // Flags to clear upon entry. Want interrupts disabled and the direction // flag cleared. diff --git a/src/system/kernel/arch/x86/64/thread.cpp b/src/system/kernel/arch/x86/64/thread.cpp index 03797773ea..e1a337fe3c 100644 --- a/src/system/kernel/arch/x86/64/thread.cpp +++ b/src/system/kernel/arch/x86/64/thread.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -197,6 +198,15 @@ arch_thread_dump_info(void* info) } +static addr_t +arch_randomize_stack_pointer(addr_t value) +{ + STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1); + value -= random_value() & (B_PAGE_SIZE - 1); + return value & ~addr_t(0xf); +} + + /*! Sets up initial thread context and enters user space */ status_t @@ -208,20 +218,14 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, TRACE("arch_thread_enter_userspace: entry %#lx, args %p %p, " "stackTop %#lx\n", entry, args1, args2, stackTop); - // Copy the little stub that calls exit_thread() when the thread entry - // function returns. - // TODO: This will become a problem later if we want to support execute - // disable, the stack shouldn't really be executable. - size_t codeSize = (addr_t)x86_end_userspace_thread_exit - - (addr_t)x86_userspace_thread_exit; - stackTop -= codeSize; - if (user_memcpy((void*)stackTop, (const void*)&x86_userspace_thread_exit, - codeSize) != B_OK) - return B_BAD_ADDRESS; + stackTop = arch_randomize_stack_pointer(stackTop); - // Copy the address of the stub to the top of the stack to act as the - // return address. - addr_t codeAddr = stackTop; + // Copy the address of the stub that calls exit_thread() when the thread + // entry function returns to the top of the stack to act as the return + // address. The stub is inside commpage. + addr_t commPageAddress = (addr_t)thread->team->commpage_address; + addr_t codeAddr = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT] + + commPageAddress; stackTop -= sizeof(codeAddr); if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr)) != B_OK) @@ -340,8 +344,10 @@ arch_setup_signal_frame(Thread* thread, struct sigaction* action, // Set up the iframe to execute the signal handler wrapper on our prepared // stack. First argument points to the frame data. + addr_t* commPageAddress = (addr_t*)thread->team->commpage_address; frame->user_sp = (addr_t)userStack; - frame->ip = ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER]; + frame->ip = commPageAddress[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + + (addr_t)commPageAddress; frame->di = (addr_t)userSignalFrameData; return B_OK; diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 7438203853..7e60ae4e2e 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -605,10 +605,12 @@ detect_cpu(int currentCPU) get_current_cpuid(&cpuid, 1); cpu->arch.feature[FEATURE_COMMON] = cpuid.eax_1.features; // edx cpu->arch.feature[FEATURE_EXT] = cpuid.eax_1.extended_features; // ecx - if (cpu->arch.vendor == VENDOR_AMD) { + if (cpu->arch.vendor == VENDOR_AMD || cpu->arch.vendor == VENDOR_INTEL) { get_current_cpuid(&cpuid, 0x80000001); cpu->arch.feature[FEATURE_EXT_AMD] = cpuid.regs.edx; // edx } + if (cpu->arch.vendor == VENDOR_INTEL) + cpu->arch.feature[FEATURE_EXT_AMD] &= IA32_FEATURES_INTEL_EXT; get_current_cpuid(&cpuid, 6); cpu->arch.feature[FEATURE_6_EAX] = cpuid.regs.eax; cpu->arch.feature[FEATURE_6_ECX] = cpuid.regs.ecx; @@ -745,6 +747,15 @@ arch_cpu_init_percpu(kernel_args* args, int cpu) } } + // If availalbe enable NX-bit (No eXecute). Boot CPU can not enable + // NX-bit here since PAE should be enabled first. + if (cpu != 0) { + if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) { + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) + | IA32_MSR_EFER_NX); + } + } + return B_OK; } @@ -862,21 +873,26 @@ arch_cpu_init_post_modules(kernel_args* args) // put the optimized functions into the commpage size_t memcpyLen = (addr_t)gOptimizedFunctions.memcpy_end - (addr_t)gOptimizedFunctions.memcpy; - fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY, + addr_t memcpyPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY, (const void*)gOptimizedFunctions.memcpy, memcpyLen); size_t memsetLen = (addr_t)gOptimizedFunctions.memset_end - (addr_t)gOptimizedFunctions.memset; - fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET, + addr_t memsetPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET, (const void*)gOptimizedFunctions.memset, memsetLen); + size_t threadExitLen = (addr_t)x86_end_userspace_thread_exit + - (addr_t)x86_userspace_thread_exit; + addr_t threadExitPosition = fill_commpage_entry( + COMMPAGE_ENTRY_X86_THREAD_EXIT, (const void*)x86_userspace_thread_exit, + threadExitLen); // add the functions to the commpage image image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, "commpage_memcpy", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMCPY], memcpyLen, - B_SYMBOL_TYPE_TEXT); - elf_add_memory_image_symbol(image, "commpage_memset", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMSET], memsetLen, - B_SYMBOL_TYPE_TEXT); + elf_add_memory_image_symbol(image, "commpage_memcpy", memcpyPosition, + memcpyLen, B_SYMBOL_TYPE_TEXT); + elf_add_memory_image_symbol(image, "commpage_memset", memsetPosition, + memsetLen, B_SYMBOL_TYPE_TEXT); + elf_add_memory_image_symbol(image, "commpage_thread_exit", + threadExitPosition, threadExitLen, B_SYMBOL_TYPE_TEXT); return B_OK; } diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp index 75e50a827e..e1836368cd 100644 --- a/src/system/kernel/arch/x86/arch_int.cpp +++ b/src/system/kernel/arch/x86/arch_int.cpp @@ -319,8 +319,9 @@ x86_page_fault_exception(struct iframe* frame) enable_interrupts(); vm_page_fault(cr2, frame->ip, - (frame->error_code & 0x2) != 0, // write access - (frame->error_code & 0x4) != 0, // userland + (frame->error_code & 0x2)!= 0, // write access + (frame->error_code & 0x10) != 0, // instruction fetch + (frame->error_code & 0x4) != 0, // userland &newip); if (newip != 0) { // the page fault handler wants us to modify the iframe to set the diff --git a/src/system/kernel/arch/x86/arch_vm.cpp b/src/system/kernel/arch/x86/arch_vm.cpp index 0aed76adb7..ae063057a5 100644 --- a/src/system/kernel/arch/x86/arch_vm.cpp +++ b/src/system/kernel/arch/x86/arch_vm.cpp @@ -728,6 +728,15 @@ arch_vm_supports_protection(uint32 protection) return false; } + // Userland and the kernel have the same setting of NX-bit. + // That's why we do not allow any area that user can access, but not execute + // and the kernel can execute. + if ((protection & (B_READ_AREA | B_WRITE_AREA)) != 0 + && (protection & B_EXECUTE_AREA) == 0 + && (protection & B_KERNEL_EXECUTE_AREA) != 0) { + return false; + } + return true; } diff --git a/src/system/kernel/arch/x86/arch_vm_translation_map.cpp b/src/system/kernel/arch/x86/arch_vm_translation_map.cpp index 836262365e..c2abe3f253 100644 --- a/src/system/kernel/arch/x86/arch_vm_translation_map.cpp +++ b/src/system/kernel/arch/x86/arch_vm_translation_map.cpp @@ -86,13 +86,16 @@ arch_vm_translation_map_init(kernel_args *args, gX86PagingMethod = new(&sPagingMethodBuffer) X86PagingMethod64Bit; #elif B_HAIKU_PHYSICAL_BITS == 64 bool paeAvailable = x86_check_feature(IA32_FEATURE_PAE, FEATURE_COMMON); - bool paeNeeded = false; - for (uint32 i = 0; i < args->num_physical_memory_ranges; i++) { - phys_addr_t end = args->physical_memory_range[i].start - + args->physical_memory_range[i].size; - if (end > 0x100000000LL) { - paeNeeded = true; - break; + bool paeNeeded = x86_check_feature(IA32_FEATURE_AMD_EXT_NX, + FEATURE_EXT_AMD); + if (!paeNeeded) { + for (uint32 i = 0; i < args->num_physical_memory_ranges; i++) { + phys_addr_t end = args->physical_memory_range[i].start + + args->physical_memory_range[i].size; + if (end > 0x100000000LL) { + paeNeeded = true; + break; + } } } diff --git a/src/system/kernel/arch/x86/asm_offsets.cpp b/src/system/kernel/arch/x86/asm_offsets.cpp index 88082f90ce..787fef10e9 100644 --- a/src/system/kernel/arch/x86/asm_offsets.cpp +++ b/src/system/kernel/arch/x86/asm_offsets.cpp @@ -34,7 +34,11 @@ dummy() DEFINE_OFFSET_MACRO(CPU_ENT, cpu_ent, fault_handler); DEFINE_OFFSET_MACRO(CPU_ENT, cpu_ent, fault_handler_stack_pointer); + // struct Team + DEFINE_OFFSET_MACRO(TEAM, Team, commpage_address); + // struct Thread + DEFINE_OFFSET_MACRO(THREAD, Thread, team); DEFINE_OFFSET_MACRO(THREAD, Thread, time_lock); DEFINE_OFFSET_MACRO(THREAD, Thread, kernel_time); DEFINE_OFFSET_MACRO(THREAD, Thread, user_time); @@ -88,6 +92,7 @@ dummy() DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, user_data); DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, handler); DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, siginfo_handler); + DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, commpage_address); // struct ucontext_t DEFINE_OFFSET_MACRO(UCONTEXT_T, __ucontext_t, uc_mcontext); diff --git a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp index d84199a44d..3f04f88775 100644 --- a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp +++ b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp @@ -59,6 +59,12 @@ X86PagingMethod64Bit::Init(kernel_args* args, fKernelPhysicalPML4 = args->arch_args.phys_pgdir; fKernelVirtualPML4 = (uint64*)(addr_t)args->arch_args.vir_pgdir; + // if availalbe enable NX-bit (No eXecute) + if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) { + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) + | IA32_MSR_EFER_NX); + } + // Ensure that the user half of the address space is clear. This removes // the temporary identity mapping made by the boot loader. memset(fKernelVirtualPML4, 0, sizeof(uint64) * 256); @@ -367,6 +373,8 @@ X86PagingMethod64Bit::PutPageTableEntryInTable(uint64* entry, page |= X86_64_PTE_USER; if ((attributes & B_WRITE_AREA) != 0) page |= X86_64_PTE_WRITABLE; + if ((attributes & B_EXECUTE_AREA) == 0) + page |= X86_64_PTE_NOT_EXECUTABLE; } else if ((attributes & B_KERNEL_WRITE_AREA) != 0) page |= X86_64_PTE_WRITABLE; diff --git a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.h b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.h index f561d9e995..e834434c78 100644 --- a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.h +++ b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.h @@ -96,6 +96,8 @@ public: uint32 memoryType); private: + static void _EnableExecutionDisable(void* dummy, int cpu); + phys_addr_t fKernelPhysicalPML4; uint64* fKernelVirtualPML4; diff --git a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp index 0e8800b15a..3f24ae5434 100644 --- a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp +++ b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp @@ -627,11 +627,13 @@ X86VMTranslationMap64Bit::Query(addr_t virtualAddress, // Translate the page state flags. if ((entry & X86_64_PTE_USER) != 0) { *_flags |= ((entry & X86_64_PTE_WRITABLE) != 0 ? B_WRITE_AREA : 0) - | B_READ_AREA; + | B_READ_AREA + | ((entry & X86_64_PTE_NOT_EXECUTABLE) == 0 ? B_EXECUTE_AREA : 0); } *_flags |= ((entry & X86_64_PTE_WRITABLE) != 0 ? B_KERNEL_WRITE_AREA : 0) | B_KERNEL_READ_AREA + | ((entry & X86_64_PTE_NOT_EXECUTABLE) == 0 ? B_KERNEL_EXECUTE_AREA : 0) | ((entry & X86_64_PTE_DIRTY) != 0 ? PAGE_MODIFIED : 0) | ((entry & X86_64_PTE_ACCESSED) != 0 ? PAGE_ACCESSED : 0) | ((entry & X86_64_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0); @@ -671,6 +673,8 @@ X86VMTranslationMap64Bit::Protect(addr_t start, addr_t end, uint32 attributes, newProtectionFlags = X86_64_PTE_USER; if ((attributes & B_WRITE_AREA) != 0) newProtectionFlags |= X86_64_PTE_WRITABLE; + if ((attributes & B_EXECUTE_AREA) == 0) + newProtectionFlags |= X86_64_PTE_NOT_EXECUTABLE; } else if ((attributes & B_KERNEL_WRITE_AREA) != 0) newProtectionFlags = X86_64_PTE_WRITABLE; diff --git a/src/system/kernel/arch/x86/paging/64bit/paging.h b/src/system/kernel/arch/x86/paging/64bit/paging.h index 2cb4fb4b06..a99afaa44c 100644 --- a/src/system/kernel/arch/x86/paging/64bit/paging.h +++ b/src/system/kernel/arch/x86/paging/64bit/paging.h @@ -59,7 +59,9 @@ #define X86_64_PTE_GLOBAL (1LL << 8) #define X86_64_PTE_NOT_EXECUTABLE (1LL << 63) #define X86_64_PTE_ADDRESS_MASK 0x000ffffffffff000L -#define X86_64_PTE_PROTECTION_MASK (X86_64_PTE_WRITABLE | X86_64_PTE_USER) +#define X86_64_PTE_PROTECTION_MASK (X86_64_PTE_NOT_EXECUTABLE \ + | X86_64_PTE_WRITABLE \ + | X86_64_PTE_USER) #define X86_64_PTE_MEMORY_TYPE_MASK (X86_64_PTE_WRITE_THROUGH \ | X86_64_PTE_CACHING_DISABLED) diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp index 34258f0c1d..90a2aee58f 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp +++ b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp @@ -148,6 +148,12 @@ struct X86PagingMethodPAE::ToPAESwitcher { // enable PAE on all CPUs call_all_cpus_sync(&_EnablePAE, (void*)(addr_t)physicalPDPT); + // if availalbe enable NX-bit (No eXecute) + if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) { + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) + | IA32_MSR_EFER_NX); + } + // set return values _virtualPDPT = pdpt; _physicalPDPT = physicalPDPT; @@ -778,6 +784,8 @@ X86PagingMethodPAE::PutPageTableEntryInTable(pae_page_table_entry* entry, page |= X86_PAE_PTE_USER; if ((attributes & B_WRITE_AREA) != 0) page |= X86_PAE_PTE_WRITABLE; + if ((attributes & B_EXECUTE_AREA) == 0) + page |= X86_PAE_PTE_NOT_EXECUTABLE; } else if ((attributes & B_KERNEL_WRITE_AREA) != 0) page |= X86_PAE_PTE_WRITABLE; diff --git a/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp index 8d6853689b..c936af436a 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp +++ b/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp @@ -687,11 +687,14 @@ X86VMTranslationMapPAE::Query(addr_t virtualAddress, // translate the page state flags if ((entry & X86_PAE_PTE_USER) != 0) { *_flags |= ((entry & X86_PAE_PTE_WRITABLE) != 0 ? B_WRITE_AREA : 0) - | B_READ_AREA; + | B_READ_AREA + | ((entry & X86_PAE_PTE_NOT_EXECUTABLE) == 0 ? B_EXECUTE_AREA : 0); } *_flags |= ((entry & X86_PAE_PTE_WRITABLE) != 0 ? B_KERNEL_WRITE_AREA : 0) | B_KERNEL_READ_AREA + | ((entry & X86_PAE_PTE_NOT_EXECUTABLE) == 0 + ? B_KERNEL_EXECUTE_AREA : 0) | ((entry & X86_PAE_PTE_DIRTY) != 0 ? PAGE_MODIFIED : 0) | ((entry & X86_PAE_PTE_ACCESSED) != 0 ? PAGE_ACCESSED : 0) | ((entry & X86_PAE_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0); @@ -733,11 +736,14 @@ X86VMTranslationMapPAE::QueryInterrupt(addr_t virtualAddress, // translate the page state flags if ((entry & X86_PAE_PTE_USER) != 0) { *_flags |= ((entry & X86_PAE_PTE_WRITABLE) != 0 ? B_WRITE_AREA : 0) - | B_READ_AREA; + | B_READ_AREA + | ((entry & X86_PAE_PTE_NOT_EXECUTABLE) == 0 ? B_EXECUTE_AREA : 0); } *_flags |= ((entry & X86_PAE_PTE_WRITABLE) != 0 ? B_KERNEL_WRITE_AREA : 0) | B_KERNEL_READ_AREA + | ((entry & X86_PAE_PTE_NOT_EXECUTABLE) == 0 + ? B_KERNEL_EXECUTE_AREA : 0) | ((entry & X86_PAE_PTE_DIRTY) != 0 ? PAGE_MODIFIED : 0) | ((entry & X86_PAE_PTE_ACCESSED) != 0 ? PAGE_ACCESSED : 0) | ((entry & X86_PAE_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0); @@ -766,6 +772,8 @@ X86VMTranslationMapPAE::Protect(addr_t start, addr_t end, uint32 attributes, newProtectionFlags = X86_PAE_PTE_USER; if ((attributes & B_WRITE_AREA) != 0) newProtectionFlags |= X86_PAE_PTE_WRITABLE; + if ((attributes & B_EXECUTE_AREA) == 0) + newProtectionFlags |= X86_PAE_PTE_NOT_EXECUTABLE; } else if ((attributes & B_KERNEL_WRITE_AREA) != 0) newProtectionFlags = X86_PAE_PTE_WRITABLE; diff --git a/src/system/kernel/arch/x86/paging/pae/paging.h b/src/system/kernel/arch/x86/paging/pae/paging.h index ae6d45b64a..0567dacc24 100644 --- a/src/system/kernel/arch/x86/paging/pae/paging.h +++ b/src/system/kernel/arch/x86/paging/pae/paging.h @@ -49,7 +49,8 @@ #define X86_PAE_PTE_IGNORED3 0x0000000000000800LL #define X86_PAE_PTE_ADDRESS_MASK 0x000ffffffffff000LL #define X86_PAE_PTE_NOT_EXECUTABLE 0x8000000000000000LL -#define X86_PAE_PTE_PROTECTION_MASK (X86_PAE_PTE_WRITABLE \ +#define X86_PAE_PTE_PROTECTION_MASK (X86_PAE_PTE_NOT_EXECUTABLE \ + |X86_PAE_PTE_WRITABLE \ | X86_PAE_PTE_USER) #define X86_PAE_PTE_MEMORY_TYPE_MASK (X86_PAE_PTE_WRITE_THROUGH \ | X86_PAE_PTE_CACHING_DISABLED) diff --git a/src/system/kernel/arch/x86/x86_signals.h b/src/system/kernel/arch/x86/x86_signals.h index 0e6cb50801..e37bb0dda5 100644 --- a/src/system/kernel/arch/x86/x86_signals.h +++ b/src/system/kernel/arch/x86/x86_signals.h @@ -11,7 +11,8 @@ void x86_initialize_commpage_signal_handler(); #ifndef __x86_64__ -addr_t x86_get_user_signal_handler_wrapper(bool beosHandler); +addr_t x86_get_user_signal_handler_wrapper(bool beosHandler, + void* commPageAddress); #endif diff --git a/src/system/kernel/commpage.cpp b/src/system/kernel/commpage.cpp index 4419bfd6cf..c54a674b07 100644 --- a/src/system/kernel/commpage.cpp +++ b/src/system/kernel/commpage.cpp @@ -15,9 +15,7 @@ static area_id sCommPageArea; -static area_id sUserCommPageArea; static addr_t* sCommPageAddress; -static addr_t* sUserCommPageAddress; static void* sFreeCommPageSpace; static image_id sCommPageImage; @@ -30,20 +28,19 @@ allocate_commpage_entry(int entry, size_t size) { void* space = sFreeCommPageSpace; sFreeCommPageSpace = ALIGN_ENTRY((addr_t)sFreeCommPageSpace + size); - sCommPageAddress[entry] = (addr_t)sUserCommPageAddress - + ((addr_t)space - (addr_t)sCommPageAddress); + sCommPageAddress[entry] = (addr_t)space - (addr_t)sCommPageAddress; dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size, (void*)sCommPageAddress[entry]); return space; } -void* +addr_t fill_commpage_entry(int entry, const void* copyFrom, size_t size) { void* space = allocate_commpage_entry(entry, size); memcpy(space, copyFrom, size); - return space; + return (addr_t)space - (addr_t)sCommPageAddress; } @@ -54,20 +51,24 @@ get_commpage_image() } +area_id +clone_commpage_area(team_id team, void** address) +{ + *address = (void*)KERNEL_USER_DATA_BASE; + return vm_clone_area(team, "commpage", address, + B_RANDOMIZED_BASE_ADDRESS, B_READ_AREA | B_EXECUTE_AREA | B_KERNEL_AREA, + REGION_PRIVATE_MAP, sCommPageArea, true); +} + + status_t commpage_init(void) { // create a read/write kernel area - sCommPageArea = create_area("commpage", (void **)&sCommPageAddress, + sCommPageArea = create_area("kernel_commpage", (void **)&sCommPageAddress, B_ANY_ADDRESS, COMMPAGE_SIZE, B_FULL_LOCK, B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA); - // clone it at a fixed address with user read/only permissions - sUserCommPageAddress = (addr_t*)USER_COMMPAGE_ADDR; - sUserCommPageArea = clone_area("user_commpage", - (void **)&sUserCommPageAddress, B_EXACT_ADDRESS, - B_READ_AREA | B_EXECUTE_AREA, sCommPageArea); - // zero it out memset(sCommPageAddress, 0, COMMPAGE_SIZE); @@ -79,10 +80,10 @@ commpage_init(void) sFreeCommPageSpace = ALIGN_ENTRY(&sCommPageAddress[COMMPAGE_TABLE_ENTRIES]); // create the image for the commpage - sCommPageImage = elf_create_memory_image("commpage", USER_COMMPAGE_ADDR, - COMMPAGE_SIZE, 0, 0); + sCommPageImage = elf_create_memory_image("commpage", 0, COMMPAGE_SIZE, 0, + 0); elf_add_memory_image_symbol(sCommPageImage, "commpage_table", - USER_COMMPAGE_ADDR, COMMPAGE_TABLE_ENTRIES * sizeof(addr_t), + 0, COMMPAGE_TABLE_ENTRIES * sizeof(addr_t), B_SYMBOL_TYPE_DATA); arch_commpage_init(); diff --git a/src/system/kernel/debug/BreakpointManager.cpp b/src/system/kernel/debug/BreakpointManager.cpp index ceed7c8fb3..f105a4040a 100644 --- a/src/system/kernel/debug/BreakpointManager.cpp +++ b/src/system/kernel/debug/BreakpointManager.cpp @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -257,12 +256,6 @@ BreakpointManager::CanAccessAddress(const void* _address, bool write) if (IS_USER_ADDRESS(address)) return true; - // a commpage address can at least be read - if (address >= USER_COMMPAGE_ADDR - && address < USER_COMMPAGE_ADDR + COMMPAGE_SIZE) { - return !write; - } - return false; } diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index 0bb496fa7b..4d18448ad6 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -1068,7 +1069,7 @@ elf_resolve_symbol(struct elf_image_info *image, elf_sym *symbol, /*! Until we have shared library support, just this links against the kernel */ static int -elf_relocate(struct elf_image_info *image) +elf_relocate(struct elf_image_info* image, struct elf_image_info* resolveImage) { int status = B_NO_ERROR; @@ -1078,7 +1079,7 @@ elf_relocate(struct elf_image_info *image) if (image->rel) { TRACE(("total %i rel relocs\n", image->rel_len / (int)sizeof(elf_rel))); - status = arch_elf_relocate_rel(image, sKernelImage, image->rel, + status = arch_elf_relocate_rel(image, resolveImage, image->rel, image->rel_len); if (status < B_OK) return status; @@ -1088,12 +1089,12 @@ elf_relocate(struct elf_image_info *image) if (image->pltrel_type == DT_REL) { TRACE(("total %i plt-relocs\n", image->pltrel_len / (int)sizeof(elf_rel))); - status = arch_elf_relocate_rel(image, sKernelImage, image->pltrel, + status = arch_elf_relocate_rel(image, resolveImage, image->pltrel, image->pltrel_len); } else { TRACE(("total %i plt-relocs\n", image->pltrel_len / (int)sizeof(elf_rela))); - status = arch_elf_relocate_rela(image, sKernelImage, + status = arch_elf_relocate_rela(image, resolveImage, (elf_rela *)image->pltrel, image->pltrel_len); } if (status < B_OK) @@ -1104,7 +1105,7 @@ elf_relocate(struct elf_image_info *image) TRACE(("total %i rel relocs\n", image->rela_len / (int)sizeof(elf_rela))); - status = arch_elf_relocate_rela(image, sKernelImage, image->rela, + status = arch_elf_relocate_rela(image, resolveImage, image->rela, image->rela_len); if (status < B_OK) return status; @@ -1287,7 +1288,7 @@ insert_preloaded_image(preloaded_elf_image *preloadedImage, bool kernel) if (status != B_OK) goto error1; - status = elf_relocate(image); + status = elf_relocate(image, sKernelImage); if (status != B_OK) goto error1; } else @@ -1363,6 +1364,7 @@ public: if (!_Read((runtime_loader_debug_area*)area->Base(), fDebugArea)) return B_BAD_ADDRESS; + fTeam = team; return B_OK; } @@ -1381,8 +1383,22 @@ public: // get the image for the address image_t image; status_t error = _FindImageAtAddress(address, image); - if (error != B_OK) + if (error != B_OK) { + // commpage requires special treatment since kernel stores symbol + // information + addr_t commPageAddress = (addr_t)fTeam->commpage_address; + if (address >= commPageAddress + && address < commPageAddress + COMMPAGE_SIZE) { + if (*_imageName) + *_imageName = "commpage"; + address -= (addr_t)commPageAddress; + error = elf_debug_lookup_symbol_address(address, _baseAddress, + _symbolName, NULL, _exactMatch); + if (_baseAddress) + *_baseAddress += (addr_t)fTeam->commpage_address; + } return error; + } strlcpy(fImageName, image.name, sizeof(fImageName)); @@ -1522,6 +1538,7 @@ public: // gcc 2.95.3 doesn't like it defined in-place private: + Team* fTeam; runtime_loader_debug_area fDebugArea; char fImageName[B_OS_NAME_LENGTH]; char fSymbolName[256]; @@ -1808,6 +1825,9 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) ssize_t length; int fd; int i; + addr_t delta = 0; + uint32 addressSpec = B_RANDOMIZED_BASE_ADDRESS; + area_id* mappedAreas = NULL; TRACE(("elf_load: entry path '%s', team %p\n", path, team)); @@ -1837,6 +1857,14 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) if (status < B_OK) goto error; + struct elf_image_info* image; + image = create_image_struct(); + if (image == NULL) { + status = B_NO_MEMORY; + goto error; + } + image->elf_header = &elfHeader; + // read program header programHeaders = (elf_phdr *)malloc( @@ -1844,7 +1872,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) if (programHeaders == NULL) { dprintf("error allocating space for program headers\n"); status = B_NO_MEMORY; - goto error; + goto error2; } TRACE(("reading in program headers at 0x%lx, length 0x%x\n", @@ -1854,12 +1882,12 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) if (length < B_OK) { status = length; dprintf("error reading in program headers\n"); - goto error; + goto error2; } if (length != elfHeader.e_phnum * elfHeader.e_phentsize) { dprintf("short read while reading in program headers\n"); status = -1; - goto error; + goto error2; } // construct a nice name for the region we have to create below @@ -1879,7 +1907,14 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) strcpy(baseName, leaf); } - // map the program's segments into memory + // map the program's segments into memory, initially with rw access + // correct area protection will be set after relocation + + mappedAreas = (area_id*)malloc(sizeof(area_id) * elfHeader.e_phnum); + if (mappedAreas == NULL) { + status = B_NO_MEMORY; + goto error2; + } image_info imageInfo; memset(&imageInfo, 0, sizeof(image_info)); @@ -1887,13 +1922,23 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) for (i = 0; i < elfHeader.e_phnum; i++) { char regionName[B_OS_NAME_LENGTH]; char *regionAddress; + char *originalRegionAddress; area_id id; + mappedAreas[i] = -1; + + if (programHeaders[i].p_type == PT_DYNAMIC) { + image->dynamic_section = programHeaders[i].p_vaddr; + continue; + } + if (programHeaders[i].p_type != PT_LOAD) continue; - regionAddress = (char *)ROUNDDOWN(programHeaders[i].p_vaddr, - B_PAGE_SIZE); + regionAddress = (char *)(ROUNDDOWN(programHeaders[i].p_vaddr, + B_PAGE_SIZE) + delta); + originalRegionAddress = regionAddress; + if (programHeaders[i].p_flags & PF_WRITE) { // rw/data segment size_t memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) @@ -1907,18 +1952,22 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) sprintf(regionName, "%s_seg%drw", baseName, i); id = vm_map_file(team->id, regionName, (void **)®ionAddress, - B_EXACT_ADDRESS, fileUpperBound, + addressSpec, fileUpperBound, B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false, fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); if (id < B_OK) { dprintf("error mapping file data: %s!\n", strerror(id)); status = B_NOT_AN_EXECUTABLE; - goto error; + goto error2; } + mappedAreas[i] = id; imageInfo.data = regionAddress; imageInfo.data_size = memUpperBound; + image->data_region.start = (addr_t)regionAddress; + image->data_region.size = memUpperBound; + // clean garbage brought by mmap (the region behind the file, // at least parts of it are the bss and have to be zeroed) addr_t start = (addr_t)regionAddress @@ -1948,7 +1997,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) if (id < B_OK) { dprintf("error allocating bss area: %s!\n", strerror(id)); status = B_NOT_AN_EXECUTABLE; - goto error; + goto error2; } } } else { @@ -1959,18 +2008,62 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); id = vm_map_file(team->id, regionName, (void **)®ionAddress, - B_EXACT_ADDRESS, segmentSize, - B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, false, - fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); + addressSpec, segmentSize, + B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false, fd, + ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); if (id < B_OK) { dprintf("error mapping file text: %s!\n", strerror(id)); status = B_NOT_AN_EXECUTABLE; - goto error; + goto error2; } + mappedAreas[i] = id; + imageInfo.text = regionAddress; imageInfo.text_size = segmentSize; + + image->text_region.start = (addr_t)regionAddress; + image->text_region.size = segmentSize; } + + if (addressSpec != B_EXACT_ADDRESS) { + addressSpec = B_EXACT_ADDRESS; + delta = regionAddress - originalRegionAddress; + } + } + + image->data_region.delta = delta; + image->text_region.delta = delta; + + // modify the dynamic ptr by the delta of the regions + image->dynamic_section += image->text_region.delta; + + status = elf_parse_dynamic_section(image); + if (status != B_OK) + goto error2; + + status = elf_relocate(image, image); + if (status != B_OK) + goto error2; + + // set correct area protection + for (i = 0; i < elfHeader.e_phnum; i++) { + if (mappedAreas[i] == -1) + continue; + + uint32 protection = 0; + + if (programHeaders[i].p_flags & PF_EXECUTE) + protection |= B_EXECUTE_AREA; + if (programHeaders[i].p_flags & PF_WRITE) + protection |= B_WRITE_AREA; + if (programHeaders[i].p_flags & PF_READ) + protection |= B_READ_AREA; + + status = vm_set_area_protection(team->id, mappedAreas[i], protection, + true); + if (status != B_OK) + goto error2; } // register the loaded image @@ -1992,9 +2085,15 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) TRACE(("elf_load: done!\n")); - *entry = elfHeader.e_entry; + *entry = elfHeader.e_entry + delta; status = B_OK; +error2: + free(mappedAreas); + + image->elf_header = NULL; + delete_elf_image(image); + error: free(programHeaders); _kern_close(fd); @@ -2241,7 +2340,7 @@ load_kernel_add_on(const char *path) if (status != B_OK) goto error5; - status = elf_relocate(image); + status = elf_relocate(image, sKernelImage); if (status < B_OK) goto error5; diff --git a/src/system/kernel/scheduler/scheduler_affine.cpp b/src/system/kernel/scheduler/scheduler_affine.cpp index 10fa82ce5a..c2a5c0c31d 100644 --- a/src/system/kernel/scheduler/scheduler_affine.cpp +++ b/src/system/kernel/scheduler/scheduler_affine.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "scheduler_common.h" #include "scheduler_tracing.h" @@ -89,19 +90,6 @@ struct scheduler_thread_data { }; -static int -_rand(void) -{ - static int next = 0; - - if (next == 0) - next = system_time(); - - next = next * 1103515245 + 12345; - return (next >> 16) & 0x7FFF; -} - - static int dump_run_queue(int argc, char **argv) { @@ -422,7 +410,7 @@ affine_reschedule(void) // skip normal threads sometimes // (twice as probable per priority level) - if ((_rand() >> (15 - priorityDiff)) != 0) + if ((fast_random_value() >> (15 - priorityDiff)) != 0) break; nextThread = lowerNextThread; diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp b/src/system/kernel/scheduler/scheduler_simple.cpp index a68a1c3a47..6b60d3ca0c 100644 --- a/src/system/kernel/scheduler/scheduler_simple.cpp +++ b/src/system/kernel/scheduler/scheduler_simple.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "scheduler_common.h" #include "scheduler_tracing.h" @@ -43,19 +44,6 @@ const bigtime_t kThreadQuantum = 3000; static Thread *sRunQueue = NULL; -static int -_rand(void) -{ - static int next = 0; - - if (next == 0) - next = system_time(); - - next = next * 1103515245 + 12345; - return (next >> 16) & 0x7FFF; -} - - static int dump_run_queue(int argc, char **argv) { @@ -272,7 +260,7 @@ simple_reschedule(void) // skip normal threads sometimes // (twice as probable per priority level) - if ((_rand() >> (15 - priorityDiff)) != 0) + if ((fast_random_value() >> (15 - priorityDiff)) != 0) break; nextThread = lowerNextThread; diff --git a/src/system/kernel/scheduler/scheduler_simple_smp.cpp b/src/system/kernel/scheduler/scheduler_simple_smp.cpp index 7ca4d7f598..c4d1e8a2df 100644 --- a/src/system/kernel/scheduler/scheduler_simple_smp.cpp +++ b/src/system/kernel/scheduler/scheduler_simple_smp.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "scheduler_common.h" #include "scheduler_tracing.h" @@ -46,19 +47,6 @@ static int32 sCPUCount = 1; static int32 sNextCPUForSelection = 0; -static int -_rand(void) -{ - static int next = 0; - - if (next == 0) - next = system_time(); - - next = next * 1103515245 + 12345; - return (next >> 16) & 0x7FFF; -} - - static int dump_run_queue(int argc, char **argv) { @@ -360,7 +348,7 @@ reschedule(void) // skip normal threads sometimes // (twice as probable per priority level) - if ((_rand() >> (15 - priorityDiff)) != 0) + if ((fast_random_value() >> (15 - priorityDiff)) != 0) break; nextThread = lowerNextThread; diff --git a/src/system/kernel/signal.cpp b/src/system/kernel/signal.cpp index 3279233357..a28533f645 100644 --- a/src/system/kernel/signal.cpp +++ b/src/system/kernel/signal.cpp @@ -892,6 +892,10 @@ setup_signal_frame(Thread* thread, struct sigaction* action, Signal* signal, memcpy(frameData.syscall_restart_parameters, thread->syscall_restart.parameters, sizeof(frameData.syscall_restart_parameters)); + + // commpage address + frameData.commpage_address = thread->team->commpage_address; + // syscall_restart_return_value is filled in by the architecture specific // code. diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 381be36458..d0d68d8c62 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -158,6 +159,9 @@ static int32 sUsedTeams = 1; static TeamNotificationService sNotificationService; +static const size_t kTeamUserDataReservedSize = 128 * B_PAGE_SIZE; +static const size_t kTeamUserDataInitialSize = 4 * B_PAGE_SIZE; + // #pragma mark - TeamListIterator @@ -447,6 +451,8 @@ Team::Team(team_id id, bool kernel) user_data_size = 0; free_user_threads = NULL; + commpage_address = NULL; + supplementary_groups = NULL; supplementary_group_count = 0; @@ -1324,23 +1330,44 @@ remove_team_from_group(Team* team) static status_t -create_team_user_data(Team* team) +create_team_user_data(Team* team, void* exactAddress = NULL) { void* address; - size_t size = 4 * B_PAGE_SIZE; + uint32 addressSpec; + + if (exactAddress != NULL) { + address = exactAddress; + addressSpec = B_EXACT_ADDRESS; + } else { + address = (void*)KERNEL_USER_DATA_BASE; + addressSpec = B_RANDOMIZED_BASE_ADDRESS; + } + + status_t result = vm_reserve_address_range(team->id, &address, addressSpec, + kTeamUserDataReservedSize, RESERVED_AVOID_BASE); + virtual_address_restrictions virtualRestrictions = {}; - virtualRestrictions.address = (void*)KERNEL_USER_DATA_BASE; - virtualRestrictions.address_specification = B_BASE_ADDRESS; + if (result == B_OK || exactAddress != NULL) { + if (exactAddress != NULL) + virtualRestrictions.address = exactAddress; + else + virtualRestrictions.address = address; + virtualRestrictions.address_specification = B_EXACT_ADDRESS; + } else { + virtualRestrictions.address = (void*)KERNEL_USER_DATA_BASE; + virtualRestrictions.address_specification = B_RANDOMIZED_BASE_ADDRESS; + } + physical_address_restrictions physicalRestrictions = {}; - team->user_data_area = create_area_etc(team->id, "user area", size, - B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions, - &physicalRestrictions, &address); + team->user_data_area = create_area_etc(team->id, "user area", + kTeamUserDataInitialSize, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0, + &virtualRestrictions, &physicalRestrictions, &address); if (team->user_data_area < 0) return team->user_data_area; team->user_data = (addr_t)address; team->used_user_data = 0; - team->user_data_size = size; + team->user_data_size = kTeamUserDataInitialSize; team->free_user_threads = NULL; return B_OK; @@ -1352,6 +1379,9 @@ delete_team_user_data(Team* team) { if (team->user_data_area >= 0) { vm_delete_area(team->id, team->user_data_area, true); + vm_unreserve_address_range(team->id, (void*)team->user_data, + kTeamUserDataReservedSize); + team->user_data = 0; team->used_user_data = 0; team->user_data_size = 0; @@ -1539,6 +1569,32 @@ team_create_thread_start_internal(void* args) // the arguments are already on the user stack, we no longer need // them in this form + // Clone commpage area + area_id commPageArea = clone_commpage_area(team->id, + &team->commpage_address); + if (commPageArea < B_OK) { + TRACE(("team_create_thread_start: clone_commpage_area() failed: %s\n", + strerror(commPageArea))); + return commPageArea; + } + + // Register commpage image + image_id commPageImage = get_commpage_image(); + image_info imageInfo; + err = get_image_info(commPageImage, &imageInfo); + if (err != B_OK) { + TRACE(("team_create_thread_start: get_image_info() failed: %s\n", + strerror(err))); + return err; + } + imageInfo.text = team->commpage_address; + image_id image = register_image(team, &imageInfo, sizeof(image_info)); + if (image < 0) { + TRACE(("team_create_thread_start: register_image() failed: %s\n", + strerror(image))); + return image; + } + // NOTE: Normally arch_thread_enter_userspace() never returns, that is // automatic variables with function scope will never be destroyed. { @@ -1572,7 +1628,7 @@ team_create_thread_start_internal(void* args) // enter userspace -- returns only in case of error return thread_enter_userspace_new_team(thread, (addr_t)entry, - programArgs, NULL); + programArgs, team->commpage_address); } @@ -1972,6 +2028,8 @@ fork_team(void) team->SetName(parentTeam->Name()); team->SetArgs(parentTeam->Args()); + team->commpage_address = parentTeam->commpage_address; + // Inherit the parent's user/group. inherit_parent_user_and_group(team, parentTeam); @@ -2035,7 +2093,7 @@ fork_team(void) while (get_next_area_info(B_CURRENT_TEAM, &areaCookie, &info) == B_OK) { if (info.area == parentTeam->user_data_area) { // don't clone the user area; just create a new one - status = create_team_user_data(team); + status = create_team_user_data(team, info.address); if (status != B_OK) break; @@ -3360,7 +3418,7 @@ team_allocate_user_thread(Team* team) while (true) { // enough space left? - size_t needed = ROUNDUP(sizeof(user_thread), 8); + size_t needed = ROUNDUP(sizeof(user_thread), 128); if (team->user_data_size - team->used_user_data < needed) { // try to resize the area if (resize_area(team->user_data_area, diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 02a574e518..93fcfe5dbb 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -821,19 +821,10 @@ create_thread_user_stack(Team* team, Thread* thread, void* _stackBase, snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_stack", thread->name, thread->id); - virtual_address_restrictions virtualRestrictions = {}; - if (thread->id == team->id) { - // The main thread gets a fixed position at the top of the stack - // address range. - stackBase = (uint8*)(USER_STACK_REGION + USER_STACK_REGION_SIZE - - areaSize); - virtualRestrictions.address_specification = B_EXACT_ADDRESS; + stackBase = (uint8*)USER_STACK_REGION; - } else { - // not a main thread - stackBase = (uint8*)(addr_t)USER_STACK_REGION; - virtualRestrictions.address_specification = B_BASE_ADDRESS; - } + virtual_address_restrictions virtualRestrictions = {}; + virtualRestrictions.address_specification = B_RANDOMIZED_BASE_ADDRESS; virtualRestrictions.address = (void*)stackBase; physical_address_restrictions physicalRestrictions = {}; diff --git a/src/system/kernel/util/Jamfile b/src/system/kernel/util/Jamfile index 02ce7ce690..a8f49b9d2a 100644 --- a/src/system/kernel/util/Jamfile +++ b/src/system/kernel/util/Jamfile @@ -14,6 +14,7 @@ KernelMergeObject kernel_util.o : queue.cpp ring_buffer.cpp RadixBitmap.cpp + Random.cpp : $(TARGET_KERNEL_PIC_CCFLAGS) -DUSING_LIBGCC ; diff --git a/src/system/kernel/util/Random.cpp b/src/system/kernel/util/Random.cpp new file mode 100644 index 0000000000..46ad125ff7 --- /dev/null +++ b/src/system/kernel/util/Random.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2013 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ + + +#include + +#include + + +static uint32 sFastLast = 0; +static uint32 sLast = 0; +static uint32 sSecureLast = 0; + +// MD4 helper definitions, based on RFC 1320 +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +#define STEP(f, a, b, c, d, xk, s) \ + (a += f((b), (c), (d)) + (xk), a = (a << (s)) | (a >> (32 - (s)))) + + +// MD4 based hash function. Simplified in order to improve performance. +static uint32 +hash(uint32* data) +{ + const uint32 kMD4Round2 = 0x5a827999; + const uint32 kMD4Round3 = 0x6ed9eba1; + + uint32 a = 0x67452301; + uint32 b = 0xefcdab89; + uint32 c = 0x98badcfe; + uint32 d = 0x10325476; + + STEP(F, a, b, c, d, data[0], 3); + STEP(F, d, a, b, c, data[1], 7); + STEP(F, c, d, a, b, data[2], 11); + STEP(F, b, c, d, a, data[3], 19); + STEP(F, a, b, c, d, data[4], 3); + STEP(F, d, a, b, c, data[5], 7); + STEP(F, c, d, a, b, data[6], 11); + STEP(F, b, c, d, a, data[7], 19); + + STEP(G, a, b, c, d, data[1] + kMD4Round2, 3); + STEP(G, d, a, b, c, data[5] + kMD4Round2, 5); + STEP(G, c, d, a, b, data[6] + kMD4Round2, 9); + STEP(G, b, c, d, a, data[2] + kMD4Round2, 13); + STEP(G, a, b, c, d, data[3] + kMD4Round2, 3); + STEP(G, d, a, b, c, data[7] + kMD4Round2, 5); + STEP(G, c, d, a, b, data[4] + kMD4Round2, 9); + STEP(G, b, c, d, a, data[0] + kMD4Round2, 13); + + STEP(H, a, b, c, d, data[1] + kMD4Round3, 3); + STEP(H, d, a, b, c, data[6] + kMD4Round3, 9); + STEP(H, c, d, a, b, data[5] + kMD4Round3, 11); + STEP(H, b, c, d, a, data[2] + kMD4Round3, 15); + STEP(H, a, b, c, d, data[3] + kMD4Round3, 3); + STEP(H, d, a, b, c, data[4] + kMD4Round3, 9); + STEP(H, c, d, a, b, data[7] + kMD4Round3, 11); + STEP(H, b, c, d, a, data[0] + kMD4Round3, 15); + + return b; +} + + +// In the following functions there are race conditions when many threads +// attempt to update static variable last. However, since such conflicts +// are non-deterministic it is not a big problem. + + +// A simple linear congruential generator +unsigned int +fast_random_value() +{ + if (sFastLast == 0) + sFastLast = system_time(); + + uint32 random = sFastLast * 1103515245 + 12345; + sFastLast = random; + return (random >> 16) & 0x7fff; +} + + +// Taken from "Random number generators: good ones are hard to find", +// Park and Miller, Communications of the ACM, vol. 31, no. 10, +// October 1988, p. 1195. +unsigned int +random_value() +{ + if (sLast == 0) + sLast = system_time(); + + uint32 hi = sLast / 127773; + uint32 lo = sLast % 127773; + + int32 random = 16807 * lo - 2836 * hi; + if (random <= 0) + random += MAX_RANDOM_VALUE; + sLast = random; + return random % (MAX_RANDOM_VALUE + 1); +} + + +unsigned int +secure_random_value() +{ + static vint32 count = 0; + + uint32 data[8]; + data[0] = atomic_add(&count, 1); + data[1] = system_time(); + data[2] = find_thread(NULL); + data[3] = smp_get_current_cpu(); + data[4] = smp_get_num_cpus(); + data[5] = sFastLast; + data[6] = sLast; + data[7] = sSecureLast; + + uint32 random = hash(data); + sSecureLast = random; + return random; +} + diff --git a/src/system/kernel/vm/VMUserAddressSpace.cpp b/src/system/kernel/vm/VMUserAddressSpace.cpp index 32730a41cb..71d48a6f51 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.cpp +++ b/src/system/kernel/vm/VMUserAddressSpace.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,15 @@ #endif +#ifdef B_HAIKU_64_BIT +const addr_t VMUserAddressSpace::kMaxRandomize = 0x8000000000ul; +const addr_t VMUserAddressSpace::kMaxInitialRandomize = 0x20000000000ul; +#else +const addr_t VMUserAddressSpace::kMaxRandomize = 0x800000ul; +const addr_t VMUserAddressSpace::kMaxInitialRandomize = 0x2000000ul; +#endif + + /*! Verifies that an area with the given aligned base and size fits into the spot defined by base and limit and checks for overflows. */ @@ -40,6 +50,14 @@ is_valid_spot(addr_t base, addr_t alignedBase, addr_t size, addr_t limit) } +static inline bool +is_randomized(uint32 addressSpec) +{ + return addressSpec == B_RANDOMIZED_ANY_ADDRESS + || addressSpec == B_RANDOMIZED_BASE_ADDRESS; +} + + VMUserAddressSpace::VMUserAddressSpace(team_id id, addr_t base, size_t size) : VMAddressSpace(id, base, size, "address space"), @@ -137,6 +155,7 @@ VMUserAddressSpace::InsertArea(VMArea* _area, size_t size, break; case B_BASE_ADDRESS: + case B_RANDOMIZED_BASE_ADDRESS: searchBase = (addr_t)addressRestrictions->address; searchEnd = fEndAddress; break; @@ -144,11 +163,8 @@ VMUserAddressSpace::InsertArea(VMArea* _area, size_t size, case B_ANY_ADDRESS: case B_ANY_KERNEL_ADDRESS: case B_ANY_KERNEL_BLOCK_ADDRESS: + case B_RANDOMIZED_ANY_ADDRESS: searchBase = fBase; - // TODO: remove this again when vm86 mode is moved into the kernel - // completely (currently needs a userland address space!) - if (searchBase == USER_BASE) - searchBase = USER_BASE_ANY; searchEnd = fEndAddress; break; @@ -156,6 +172,11 @@ VMUserAddressSpace::InsertArea(VMArea* _area, size_t size, return B_BAD_VALUE; } + // TODO: remove this again when vm86 mode is moved into the kernel + // completely (currently needs a userland address space!) + if (addressRestrictions->address_specification != B_EXACT_ADDRESS) + searchBase = max_c(searchBase, USER_BASE_ANY); + status = _InsertAreaSlot(searchBase, size, searchEnd, addressRestrictions->address_specification, addressRestrictions->alignment, area, allocationFlags); @@ -371,6 +392,29 @@ VMUserAddressSpace::Dump() const } +addr_t +VMUserAddressSpace::_RandomizeAddress(addr_t start, addr_t end, + size_t alignment, bool initial) +{ + ASSERT((start & addr_t(alignment - 1)) == 0); + + if (start == end) + return start; + + addr_t range = end - start; + if (initial) + range = min_c(range, kMaxInitialRandomize); + else + range = min_c(range, kMaxRandomize); + + addr_t random = secure_get_random(); + random %= range; + random &= ~addr_t(alignment - 1); + + return start + random; +} + + /*! Finds a reserved area that covers the region spanned by \a start and \a size, inserts the \a area into that region and makes sure that there are reserved regions for the remaining parts. @@ -459,6 +503,7 @@ VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end, VMUserArea* last = NULL; VMUserArea* next; bool foundSpot = false; + addr_t originalStart = 0; TRACE(("VMUserAddressSpace::_InsertAreaSlot: address space %p, start " "0x%lx, size %ld, end 0x%lx, addressSpec %" B_PRIu32 ", area %p\n", @@ -491,6 +536,11 @@ VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end, start = ROUNDUP(start, alignment); + if (addressSpec == B_RANDOMIZED_BASE_ADDRESS) { + originalStart = start; + start = _RandomizeAddress(start, end - size, alignment, true); + } + // walk up to the spot where we should start searching second_chance: VMUserAreaList::Iterator it = fAreas.GetIterator(); @@ -510,13 +560,23 @@ second_chance: case B_ANY_ADDRESS: case B_ANY_KERNEL_ADDRESS: case B_ANY_KERNEL_BLOCK_ADDRESS: + case B_RANDOMIZED_ANY_ADDRESS: + case B_BASE_ADDRESS: + case B_RANDOMIZED_BASE_ADDRESS: { // find a hole big enough for a new area if (last == NULL) { // see if we can build it at the beginning of the virtual map addr_t alignedBase = ROUNDUP(start, alignment); - if (is_valid_spot(start, alignedBase, size, - next == NULL ? end : next->Base())) { + addr_t nextBase = next == NULL ? end : min_c(next->Base(), end); + if (is_valid_spot(start, alignedBase, size, nextBase)) { + + addr_t rangeEnd = min_c(nextBase - size, end); + if (is_randomized(addressSpec)) { + alignedBase = _RandomizeAddress(alignedBase, rangeEnd, + alignment); + } + foundSpot = true; area->SetBase(alignedBase); break; @@ -527,11 +587,19 @@ second_chance: } // keep walking - while (next != NULL) { + while (next != NULL && next->Base() + size - 1 <= end) { addr_t alignedBase = ROUNDUP(last->Base() + last->Size(), alignment); + addr_t nextBase = min_c(end, next->Base()); if (is_valid_spot(last->Base() + (last->Size() - 1), - alignedBase, size, next->Base())) { + alignedBase, size, nextBase)) { + + addr_t rangeEnd = min_c(nextBase - size, end); + if (is_randomized(addressSpec)) { + alignedBase = _RandomizeAddress(alignedBase, + rangeEnd, alignment); + } + foundSpot = true; area->SetBase(alignedBase); break; @@ -548,10 +616,33 @@ second_chance: alignment); if (is_valid_spot(last->Base() + (last->Size() - 1), alignedBase, size, end)) { + + if (is_randomized(addressSpec)) { + alignedBase = _RandomizeAddress(alignedBase, end - size, + alignment); + } + // got a spot foundSpot = true; area->SetBase(alignedBase); break; + } else if (addressSpec == B_BASE_ADDRESS + || addressSpec == B_RANDOMIZED_BASE_ADDRESS) { + + // we didn't find a free spot in the requested range, so we'll + // try again without any restrictions + start = USER_BASE_ANY; + if (!is_randomized(addressSpec)) + addressSpec = B_ANY_ADDRESS; + else if (start == originalStart) + addressSpec = B_RANDOMIZED_ANY_ADDRESS; + else { + start = originalStart; + addressSpec = B_RANDOMIZED_BASE_ADDRESS; + } + + last = NULL; + goto second_chance; } else if (area->id != RESERVED_AREA_ID) { // We didn't find a free spot - if there are any reserved areas, // we can now test those for free space @@ -562,7 +653,8 @@ second_chance: if (next->id != RESERVED_AREA_ID) { last = next; continue; - } + } else if (next->Base() + size - 1 > end) + break; // TODO: take free space after the reserved area into // account! @@ -582,23 +674,49 @@ second_chance: if ((next->protection & RESERVED_AVOID_BASE) == 0 && alignedBase == next->Base() && next->Size() >= size) { + + addr_t rangeEnd = min_c(next->Size() - size, end); + if (is_randomized(addressSpec)) { + alignedBase = _RandomizeAddress(next->Base(), + rangeEnd, alignment); + } + addr_t offset = alignedBase - next->Base(); + // The new area will be placed at the beginning of the // reserved area and the reserved area will be offset // and resized foundSpot = true; - next->SetBase(next->Base() + size); - next->SetSize(next->Size() - size); + next->SetBase(next->Base() + offset + size); + next->SetSize(next->Size() - offset - size); area->SetBase(alignedBase); break; } if (is_valid_spot(next->Base(), alignedBase, size, - next->Base() + (next->Size() - 1))) { + min_c(next->Base() + next->Size() - 1, end))) { // The new area will be placed at the end of the // reserved area, and the reserved area will be resized // to make space - alignedBase = ROUNDDOWN( - next->Base() + next->Size() - size, alignment); + + if (is_randomized(addressSpec)) { + addr_t alignedNextBase = ROUNDUP(next->Base(), + alignment); + + addr_t startRange = next->Base() + next->Size(); + startRange -= size + kMaxRandomize; + startRange = ROUNDDOWN(startRange, alignment); + + startRange = max_c(startRange, alignedNextBase); + + addr_t rangeEnd + = min_c(next->Base() + next->Size() - size, + end); + alignedBase = _RandomizeAddress(startRange, + rangeEnd, alignment); + } else { + alignedBase = ROUNDDOWN( + next->Base() + next->Size() - size, alignment); + } foundSpot = true; next->SetSize(alignedBase - next->Base()); @@ -610,55 +728,10 @@ second_chance: last = next; } } + break; } - case B_BASE_ADDRESS: - { - // find a hole big enough for a new area beginning with "start" - if (last == NULL) { - // see if we can build it at the beginning of the specified - // start - if (next == NULL || next->Base() > start + (size - 1)) { - foundSpot = true; - area->SetBase(start); - break; - } - - last = next; - next = it.Next(); - } - - // keep walking - while (next != NULL) { - if (next->Base() - (last->Base() + last->Size()) >= size) { - // we found a spot (it'll be filled up below) - break; - } - - last = next; - next = it.Next(); - } - - addr_t lastEnd = last->Base() + (last->Size() - 1); - if (next != NULL || end - lastEnd >= size) { - // got a spot - foundSpot = true; - if (lastEnd < start) - area->SetBase(start); - else - area->SetBase(lastEnd + 1); - break; - } - - // we didn't find a free spot in the requested range, so we'll - // try again without any restrictions - start = fBase; - addressSpec = B_ANY_ADDRESS; - last = NULL; - goto second_chance; - } - case B_EXACT_ADDRESS: // see if we can create it exactly here if ((last == NULL || last->Base() + (last->Size() - 1) < start) diff --git a/src/system/kernel/vm/VMUserAddressSpace.h b/src/system/kernel/vm/VMUserAddressSpace.h index fe5d37c246..0aa42612b6 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.h +++ b/src/system/kernel/vm/VMUserAddressSpace.h @@ -53,6 +53,9 @@ public: virtual void Dump() const; private: + static addr_t _RandomizeAddress(addr_t start, addr_t end, + size_t alignment, bool initial = false); + status_t _InsertAreaIntoReservedRegion(addr_t start, size_t size, VMUserArea* area, uint32 allocationFlags); @@ -62,6 +65,9 @@ private: uint32 allocationFlags); private: + static const addr_t kMaxRandomize; + static const addr_t kMaxInitialRandomize; + VMUserAreaList fAreas; mutable VMUserArea* fAreaHint; }; diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 6e809b66a0..f5aa4e2184 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -267,13 +267,14 @@ static cache_info* sCacheInfoTable; static void delete_area(VMAddressSpace* addressSpace, VMArea* area, bool addressSpaceCleanup); static status_t vm_soft_fault(VMAddressSpace* addressSpace, addr_t address, - bool isWrite, bool isUser, vm_page** wirePage, + bool isWrite, bool isExecute, bool isUser, vm_page** wirePage, VMAreaWiredRange* wiredRange = NULL); static status_t map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset, const char* areaName, addr_t size, int wiring, int protection, int mapping, uint32 flags, const virtual_address_restrictions* addressRestrictions, bool kernel, VMArea** _area, void** _virtualAddress); +static void fix_protection(uint32* protection); // #pragma mark - @@ -315,6 +316,7 @@ enum { PAGE_FAULT_ERROR_KERNEL_ONLY, PAGE_FAULT_ERROR_WRITE_PROTECTED, PAGE_FAULT_ERROR_READ_PROTECTED, + PAGE_FAULT_ERROR_EXECUTE_PROTECTED, PAGE_FAULT_ERROR_KERNEL_BAD_USER_MEMORY, PAGE_FAULT_ERROR_NO_ADDRESS_SPACE }; @@ -346,6 +348,10 @@ public: case PAGE_FAULT_ERROR_READ_PROTECTED: out.Print("page fault error: area: %ld, read protected", fArea); break; + case PAGE_FAULT_ERROR_EXECUTE_PROTECTED: + out.Print("page fault error: area: %ld, execute protected", + fArea); + break; case PAGE_FAULT_ERROR_KERNEL_BAD_USER_MEMORY: out.Print("page fault error: kernel touching bad user memory"); break; @@ -1219,6 +1225,8 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size, case B_BASE_ADDRESS: case B_ANY_KERNEL_ADDRESS: case B_ANY_KERNEL_BLOCK_ADDRESS: + case B_RANDOMIZED_ANY_ADDRESS: + case B_RANDOMIZED_BASE_ADDRESS: break; default: @@ -2520,10 +2528,12 @@ vm_copy_area(team_id team, const char* name, void** _address, } -static status_t +status_t vm_set_area_protection(team_id team, area_id areaID, uint32 newProtection, bool kernel) { + fix_protection(&newProtection); + TRACE(("vm_set_area_protection(team = %#" B_PRIx32 ", area = %#" B_PRIx32 ", protection = %#" B_PRIx32 ")\n", team, areaID, newProtection)); @@ -3992,8 +4002,8 @@ forbid_page_faults(void) status_t -vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser, - addr_t* newIP) +vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isExecute, + bool isUser, addr_t* newIP) { FTRACE(("vm_page_fault: page fault at 0x%lx, ip 0x%lx\n", address, faultAddress)); @@ -4036,8 +4046,8 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser, } if (status == B_OK) { - status = vm_soft_fault(addressSpace, pageAddress, isWrite, isUser, - NULL); + status = vm_soft_fault(addressSpace, pageAddress, isWrite, isExecute, + isUser, NULL); } if (status < B_OK) { @@ -4072,8 +4082,8 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser, "\"%s\" (%" B_PRId32 ") tried to %s address %#lx, ip %#lx " "(\"%s\" +%#lx)\n", thread->name, thread->id, thread->team->Name(), thread->team->id, - isWrite ? "write" : "read", address, faultAddress, - area ? area->name : "???", faultAddress - (area ? + isWrite ? "write" : (isExecute ? "execute" : "read"), address, + faultAddress, area ? area->name : "???", faultAddress - (area ? area->Base() : 0x0)); // We can print a stack trace of the userland thread here. @@ -4362,7 +4372,8 @@ fault_get_page(PageFaultContext& context) */ static status_t vm_soft_fault(VMAddressSpace* addressSpace, addr_t originalAddress, - bool isWrite, bool isUser, vm_page** wirePage, VMAreaWiredRange* wiredRange) + bool isWrite, bool isExecute, bool isUser, vm_page** wirePage, + VMAreaWiredRange* wiredRange) { FTRACE(("vm_soft_fault: thid 0x%" B_PRIx32 " address 0x%" B_PRIxADDR ", " "isWrite %d, isUser %d\n", thread_get_current_thread_id(), @@ -4417,7 +4428,16 @@ vm_soft_fault(VMAddressSpace* addressSpace, addr_t originalAddress, VMPageFaultTracing::PAGE_FAULT_ERROR_WRITE_PROTECTED)); status = B_PERMISSION_DENIED; break; - } else if (!isWrite && (protection + } else if (isExecute && (protection + & (B_EXECUTE_AREA + | (isUser ? 0 : B_KERNEL_EXECUTE_AREA))) == 0) { + dprintf("instruction fetch attempted on execute-protected area 0x%" + B_PRIx32 " at %p\n", area->id, (void*)originalAddress); + TPF(PageFaultError(area->id, + VMPageFaultTracing::PAGE_FAULT_ERROR_EXECUTE_PROTECTED)); + status = B_PERMISSION_DENIED; + break; + } else if (!isWrite && !isExecute && (protection & (B_READ_AREA | (isUser ? 0 : B_KERNEL_READ_AREA))) == 0) { dprintf("read access attempted on read-protected area 0x%" B_PRIx32 " at %p\n", area->id, (void*)originalAddress); @@ -4754,7 +4774,8 @@ vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type) /*! This function enforces some protection properties: - - if B_WRITE_AREA is set, B_WRITE_KERNEL_AREA is set as well + - if B_WRITE_AREA is set, B_KERNEL_WRITE_AREA is set as well + - if B_EXECUTE_AREA is set, B_KERNEL_EXECUTE_AREA is set as well - if only B_READ_AREA has been set, B_KERNEL_READ_AREA is also set - if no protection is specified, it defaults to B_KERNEL_READ_AREA and B_KERNEL_WRITE_AREA. @@ -4768,6 +4789,8 @@ fix_protection(uint32* protection) *protection |= B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA; else *protection |= B_KERNEL_READ_AREA; + if ((*protection & B_EXECUTE_AREA) != 0) + *protection |= B_KERNEL_EXECUTE_AREA; } } @@ -5220,8 +5243,8 @@ vm_wire_page(team_id team, addr_t address, bool writable, cacheChainLocker.Unlock(); addressSpaceLocker.Unlock(); - error = vm_soft_fault(addressSpace, pageAddress, writable, isUser, - &page, &info->range); + error = vm_soft_fault(addressSpace, pageAddress, writable, false, + isUser, &page, &info->range); if (error != B_OK) { // The page could not be mapped -- clean up. @@ -5399,7 +5422,7 @@ lock_memory_etc(team_id team, void* address, size_t numBytes, uint32 flags) addressSpaceLocker.Unlock(); error = vm_soft_fault(addressSpace, nextAddress, writable, - isUser, &page, range); + false, isUser, &page, range); addressSpaceLocker.Lock(); cacheChainLocker.SetTo(vm_area_get_locked_cache(area)); @@ -5788,8 +5811,6 @@ _get_next_area_info(team_id team, ssize_t* cookie, area_info* info, size_t size) status_t set_area_protection(area_id area, uint32 newProtection) { - fix_protection(&newProtection); - return vm_set_area_protection(VMAddressSpace::KernelID(), area, newProtection, true); } @@ -6017,8 +6038,6 @@ _user_set_area_protection(area_id area, uint32 newProtection) if ((newProtection & ~B_USER_PROTECTION) != 0) return B_BAD_VALUE; - fix_protection(&newProtection); - return vm_set_area_protection(VMAddressSpace::CurrentID(), area, newProtection, false); } @@ -6125,6 +6144,11 @@ _user_create_area(const char* userName, void** userAddress, uint32 addressSpec, && IS_KERNEL_ADDRESS(address)) return B_BAD_VALUE; + if (addressSpec == B_ANY_ADDRESS) + addressSpec = B_RANDOMIZED_ANY_ADDRESS; + if (addressSpec == B_BASE_ADDRESS) + addressSpec = B_RANDOMIZED_BASE_ADDRESS; + fix_protection(&protection); virtual_address_restrictions virtualRestrictions = {}; diff --git a/src/system/ldscripts/x86/runtime_loader.ld b/src/system/ldscripts/x86/runtime_loader.ld index 2bc53c699f..ae1062f74a 100644 --- a/src/system/ldscripts/x86/runtime_loader.ld +++ b/src/system/ldscripts/x86/runtime_loader.ld @@ -5,7 +5,7 @@ ENTRY(runtime_loader) SEARCH_DIR("libgcc"); SECTIONS { - . = 0x00100000 + SIZEOF_HEADERS; + . = 0x00000000 + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } diff --git a/src/system/ldscripts/x86_64/runtime_loader.ld b/src/system/ldscripts/x86_64/runtime_loader.ld index a83a6de457..ee0b42f2e3 100644 --- a/src/system/ldscripts/x86_64/runtime_loader.ld +++ b/src/system/ldscripts/x86_64/runtime_loader.ld @@ -5,7 +5,7 @@ ENTRY(runtime_loader) SEARCH_DIR("libgcc"); SECTIONS { - . = 0x00200000 + SIZEOF_HEADERS; + . = 0x00000000 + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } diff --git a/src/system/libroot/libroot_init.c b/src/system/libroot/libroot_init.c index 68137366eb..cf6fc668fc 100644 --- a/src/system/libroot/libroot_init.c +++ b/src/system/libroot/libroot_init.c @@ -24,6 +24,8 @@ struct rld_export *__gRuntimeLoader = NULL; // This little bugger is set to something meaningful by the runtime loader // Ugly, eh? +const void* __gCommPageAddress; + char *__progname = NULL; int __libc_argc; char **__libc_argv; @@ -44,6 +46,8 @@ void initialize_before(image_id imageID) { char *programPath = __gRuntimeLoader->program_args->args[0]; + __gCommPageAddress = __gRuntimeLoader->commpage_address; + if (programPath) { if ((__progname = strrchr(programPath, '/')) == NULL) __progname = programPath; @@ -62,7 +66,7 @@ initialize_before(image_id imageID) pthread_self()->id = find_thread(NULL); - __init_time(); + __init_time((addr_t)__gCommPageAddress); __init_heap(); __init_env(__gRuntimeLoader->program_args); __init_heap_post_env(); diff --git a/src/system/libroot/os/arch/x86/syscalls.inc b/src/system/libroot/os/arch/x86/syscalls.inc index 95aa740535..517d650d09 100644 --- a/src/system/libroot/os/arch/x86/syscalls.inc +++ b/src/system/libroot/os/arch/x86/syscalls.inc @@ -17,11 +17,13 @@ #include #include -#define _SYSCALL(name, n) \ - .align 8; \ - FUNCTION(name): \ - movl $n,%eax; \ - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_SYSCALL * 4); \ +#define _SYSCALL(name, n) \ + .align 8; \ + FUNCTION(name): \ + movl $n, %eax; \ + movl __gCommPageAddress, %edx; \ + addl 4 * COMMPAGE_ENTRY_X86_SYSCALL(%edx), %edx; \ + jmp %edx; \ FUNCTION_END(name) #define SYSCALL0(name, n) _SYSCALL(name, n) diff --git a/src/system/libroot/os/time.cpp b/src/system/libroot/os/time.cpp index 19d29536a5..7b882cd8e7 100644 --- a/src/system/libroot/os/time.cpp +++ b/src/system/libroot/os/time.cpp @@ -24,10 +24,11 @@ static struct real_time_data* sRealTimeData; void -__init_time(void) +__init_time(addr_t commPageTable) { sRealTimeData = (struct real_time_data*) - USER_COMMPAGE_TABLE[COMMPAGE_ENTRY_REAL_TIME_DATA]; + (((addr_t*)commPageTable)[COMMPAGE_ENTRY_REAL_TIME_DATA] + + commPageTable); __arch_init_time(sRealTimeData, false); } diff --git a/src/system/libroot/posix/malloc/arch-specific.cpp b/src/system/libroot/posix/malloc/arch-specific.cpp index 0bcaac8fcd..54d2fe00ad 100644 --- a/src/system/libroot/posix/malloc/arch-specific.cpp +++ b/src/system/libroot/posix/malloc/arch-specific.cpp @@ -99,12 +99,12 @@ __init_heap(void) // size of the heap is guaranteed until the space is really needed. sHeapBase = (void *)kHeapReservationBase; status_t status = _kern_reserve_address_range((addr_t *)&sHeapBase, - B_EXACT_ADDRESS, kHeapReservationSize); + B_RANDOMIZED_BASE_ADDRESS, kHeapReservationSize); if (status != B_OK) sHeapBase = NULL; sHeapArea = create_area("heap", (void **)&sHeapBase, - status == B_OK ? B_EXACT_ADDRESS : B_BASE_ADDRESS, + status == B_OK ? B_EXACT_ADDRESS : B_RANDOMIZED_BASE_ADDRESS, kInitialHeapSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (sHeapArea < B_OK) return sHeapArea; @@ -271,8 +271,8 @@ hoardSbrk(long size) // allocation. if (area < 0) { base = (void*)(sFreeHeapBase + sHeapAreaSize); - area = create_area("heap", &base, B_BASE_ADDRESS, newHeapSize, - B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + area = create_area("heap", &base, B_RANDOMIZED_BASE_ADDRESS, + newHeapSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); } if (area < 0) { diff --git a/src/system/libroot/posix/string/arch/x86/arch_string.S b/src/system/libroot/posix/string/arch/x86/arch_string.S index 4ab85e7da0..1518baa207 100644 --- a/src/system/libroot/posix/string/arch/x86/arch_string.S +++ b/src/system/libroot/posix/string/arch/x86/arch_string.S @@ -10,9 +10,13 @@ .align 4 FUNCTION(memcpy): - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMCPY * 4) + movl __gCommPageAddress, %eax + addl 4 * COMMPAGE_ENTRY_X86_MEMCPY(%eax), %eax + jmp *%eax FUNCTION_END(memcpy) FUNCTION(memset): - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMSET * 4) + movl __gCommPageAddress, %eax + addl 4 * COMMPAGE_ENTRY_X86_MEMSET(%eax), %eax + jmp *%eax FUNCTION_END(memset) diff --git a/src/system/libroot/posix/string/arch/x86_64/arch_string.S b/src/system/libroot/posix/string/arch/x86_64/arch_string.S index 8bbadb31ca..e1273fdc3c 100644 --- a/src/system/libroot/posix/string/arch/x86_64/arch_string.S +++ b/src/system/libroot/posix/string/arch/x86_64/arch_string.S @@ -8,10 +8,15 @@ FUNCTION(memcpy): - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMCPY * 8) + movq __gCommPageAddress@GOTPCREL(%rip), %rax + movq (%rax), %rax + addq 8 * COMMPAGE_ENTRY_X86_MEMCPY(%rax), %rax + jmp *%rax FUNCTION_END(memcpy) - FUNCTION(memset): - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMSET * 8) + movq __gCommPageAddress@GOTPCREL(%rip), %rax + movq (%rax), %rax + addq 8 * COMMPAGE_ENTRY_X86_MEMSET(%rax), %rax + jmp *%rax FUNCTION_END(memset) diff --git a/src/system/libroot/posix/sys/mman.cpp b/src/system/libroot/posix/sys/mman.cpp index 17866ee9ed..68dbf0a7a2 100644 --- a/src/system/libroot/posix/sys/mman.cpp +++ b/src/system/libroot/posix/sys/mman.cpp @@ -113,9 +113,13 @@ mmap(void* address, size_t length, int protection, int flags, int fd, int mapping = (flags & MAP_SHARED) != 0 ? REGION_NO_PRIVATE_MAP : REGION_PRIVATE_MAP; - uint32 addressSpec = address == NULL ? B_ANY_ADDRESS : B_BASE_ADDRESS; + uint32 addressSpec; if ((flags & MAP_FIXED) != 0) addressSpec = B_EXACT_ADDRESS; + else if (address != NULL) + addressSpec = B_RANDOMIZED_BASE_ADDRESS; + else + addressSpec = B_RANDOMIZED_ANY_ADDRESS; uint32 areaProtection = 0; if ((protection & PROT_READ) != 0) diff --git a/src/system/runtime_loader/Jamfile b/src/system/runtime_loader/Jamfile index d687912673..11bc81122e 100644 --- a/src/system/runtime_loader/Jamfile +++ b/src/system/runtime_loader/Jamfile @@ -91,7 +91,7 @@ Ld runtime_loader : $(TARGET_STATIC_LIBSUPC++) $(TARGET_GCC_LIBGCC) : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/runtime_loader.ld - : --no-undefined + : --no-undefined -shared -soname=runtime_loader ; HaikuSubInclude arch $(TARGET_ARCH) ; diff --git a/src/system/runtime_loader/elf.cpp b/src/system/runtime_loader/elf.cpp index 9415d73b55..edaf863b54 100644 --- a/src/system/runtime_loader/elf.cpp +++ b/src/system/runtime_loader/elf.cpp @@ -1031,7 +1031,7 @@ rldelf_init(void) runtime_loader_debug_area *area; area_id areaID = _kern_create_area(RUNTIME_LOADER_DEBUG_AREA_NAME, - (void **)&area, B_ANY_ADDRESS, size, B_NO_LOCK, + (void **)&area, B_RANDOMIZED_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (areaID < B_OK) { FATAL("Failed to create debug area.\n"); diff --git a/src/system/runtime_loader/export.cpp b/src/system/runtime_loader/export.cpp index 62275c5974..adfd2a4dd9 100644 --- a/src/system/runtime_loader/export.cpp +++ b/src/system/runtime_loader/export.cpp @@ -65,4 +65,5 @@ void rldexport_init(void) { gRuntimeLoader.program_args = gProgramArgs; + gRuntimeLoader.commpage_address = __gCommPageAddress; } diff --git a/src/system/runtime_loader/heap.cpp b/src/system/runtime_loader/heap.cpp index 02dc286b02..8cd57abf54 100644 --- a/src/system/runtime_loader/heap.cpp +++ b/src/system/runtime_loader/heap.cpp @@ -178,8 +178,8 @@ static status_t add_area(size_t size) { void *base; - area_id area = _kern_create_area("rld heap", &base, B_ANY_ADDRESS, size, - B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + area_id area = _kern_create_area("rld heap", &base, + B_RANDOMIZED_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (area < B_OK) return area; diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp index 6c6c460285..3bbe34bde2 100644 --- a/src/system/runtime_loader/images.cpp +++ b/src/system/runtime_loader/images.cpp @@ -165,7 +165,7 @@ topological_sort(image_t* image, uint32 slot, image_t** initList, /*! Finds the load address and address specifier of the given image region. */ static void -get_image_region_load_address(image_t* image, uint32 index, int32 lastDelta, +get_image_region_load_address(image_t* image, uint32 index, long lastDelta, bool fixed, addr_t& loadAddress, uint32& addressSpecifier) { if (image->dynamic_ptr != 0 && !fixed) { @@ -173,7 +173,7 @@ get_image_region_load_address(image_t* image, uint32 index, int32 lastDelta, if (index == 0) { // but only the first segment gets a free ride loadAddress = RLD_PROGRAM_BASE; - addressSpecifier = B_BASE_ADDRESS; + addressSpecifier = B_RANDOMIZED_BASE_ADDRESS; } else { loadAddress = image->regions[index].vmstart + lastDelta; addressSpecifier = B_EXACT_ADDRESS; @@ -298,7 +298,7 @@ map_image(int fd, char const* path, image_t* image, bool fixed) addr_t loadAddress; size_t reservedSize = 0; size_t length = 0; - uint32 addressSpecifier = B_ANY_ADDRESS; + uint32 addressSpecifier = B_RANDOMIZED_ANY_ADDRESS; for (uint32 i = 0; i < image->num_regions; i++) { // for BeOS compatibility: if we load an old BeOS executable, we diff --git a/src/system/runtime_loader/runtime_loader.cpp b/src/system/runtime_loader/runtime_loader.cpp index 3389103901..140a7574b6 100644 --- a/src/system/runtime_loader/runtime_loader.cpp +++ b/src/system/runtime_loader/runtime_loader.cpp @@ -22,6 +22,7 @@ struct user_space_program_args *gProgramArgs; +void *__gCommPageAddress; static const char * @@ -366,12 +367,13 @@ out: specified by its ld-script. */ int -runtime_loader(void *_args) +runtime_loader(void* _args, void* commpage) { void *entry = NULL; int returnCode; gProgramArgs = (struct user_space_program_args *)_args; + __gCommPageAddress = commpage; // Relocate the args and env arrays -- they are organized in a contiguous // buffer which the kernel just copied into user space without adjusting the diff --git a/src/system/runtime_loader/runtime_loader_private.h b/src/system/runtime_loader/runtime_loader_private.h index f3f6dd38e0..2720a659a8 100644 --- a/src/system/runtime_loader/runtime_loader_private.h +++ b/src/system/runtime_loader/runtime_loader_private.h @@ -43,6 +43,7 @@ struct SymbolLookupCache; extern struct user_space_program_args* gProgramArgs; +extern void* __gCommPageAddress; extern struct rld_export gRuntimeLoader; extern char* (*gGetEnv)(const char* name); extern bool gProgramLoaded; @@ -53,7 +54,7 @@ extern image_t* gProgramImage; extern "C" { #endif -int runtime_loader(void* arg); +int runtime_loader(void* arg, void* commpage); int open_executable(char* name, image_type type, const char* rpath, const char* programPath, const char* compatibilitySubDir); status_t test_executable(const char* path, char* interpreter); diff --git a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceAddressView.cpp b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceAddressView.cpp index 83857bd586..4ff92bfb54 100644 --- a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceAddressView.cpp +++ b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceAddressView.cpp @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * Alexander von Gluck, kallisti5@unixzen.com + * Alexander von Gluck, kallisti5@unixzen.com * John Scipione, jscipione@gmail.com */ diff --git a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceAddressView.h b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceAddressView.h index 8d700e84c8..29f12a47b2 100644 --- a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceAddressView.h +++ b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceAddressView.h @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * Alexander von Gluck, kallisti5@unixzen.com + * Alexander von Gluck, kallisti5@unixzen.com * John Scipione, jscipione@gmail.com */ #ifndef INTERFACE_ADDRESS_VIEW_H diff --git a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceHardwareView.cpp b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceHardwareView.cpp index c5d9e6453e..16b559c232 100644 --- a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceHardwareView.cpp +++ b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceHardwareView.cpp @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * Alexander von Gluck, kallisti5@unixzen.com + * Alexander von Gluck, kallisti5@unixzen.com * John Scipione, jscipione@gmail.com */ @@ -22,6 +22,8 @@ #include #include +#include + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "IntefaceHardwareView" @@ -57,7 +59,19 @@ InterfaceHardwareView::InterfaceHardwareView(BRect frame, fLinkSpeedField = new BStringView("link speed field", ""); fLinkSpeedField->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); - Revert(); + // TODO: These metrics may be better in a BScrollView? + BStringView* linkTx = new BStringView("tx label", + B_TRANSLATE("Sent:")); + linkTx->SetAlignment(B_ALIGN_RIGHT); + fLinkTxField = new BStringView("tx field", ""); + fLinkTxField ->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); + BStringView* linkRx = new BStringView("rx label", + B_TRANSLATE("Received:")); + linkRx->SetAlignment(B_ALIGN_RIGHT); + fLinkRxField = new BStringView("rx field", ""); + fLinkRxField ->SetExplicitMinSize(BSize(minimumWidth, B_SIZE_UNSET)); + + Update(); // Populate the fields BLayoutBuilder::Group<>(this) @@ -68,6 +82,10 @@ InterfaceHardwareView::InterfaceHardwareView(BRect frame, .Add(fMacAddressField, 1, 1) .Add(linkSpeed, 0, 2) .Add(fLinkSpeedField, 1, 2) + .Add(linkTx, 0, 3) + .Add(fLinkTxField, 1, 3) + .Add(linkRx, 0, 4) + .Add(fLinkRxField, 1, 4) .End() .AddGlue() .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, @@ -106,11 +124,27 @@ InterfaceHardwareView::MessageReceived(BMessage* message) status_t InterfaceHardwareView::Revert() +{ + Update(); + return B_OK; +} + + +status_t +InterfaceHardwareView::Update() { // Populate fields with current settings - if (fSettings->HasLink()) - fStatusField->SetText(B_TRANSLATE("connected")); - else + if (fSettings->HasLink()) { + if (fSettings->IsWireless()) { + BString network = fSettings->WirelessNetwork(); + network.Prepend(" ("); + network.Prepend(B_TRANSLATE("connected")); + network.Append(")"); + fStatusField->SetText(network.String()); + } else { + fStatusField->SetText(B_TRANSLATE("connected")); + } + } else fStatusField->SetText(B_TRANSLATE("disconnected")); fMacAddressField->SetText(fSettings->HardwareAddress()); @@ -118,6 +152,18 @@ InterfaceHardwareView::Revert() // TODO : Find how to get link speed fLinkSpeedField->SetText("100 Mb/s"); + // Update Link stats + ifreq_stats stats; + char buffer[100]; + fSettings->Stats(&stats); + snprintf(buffer, sizeof(buffer), B_TRANSLATE("%" B_PRIu64 " KBytes"), + stats.send.bytes / 1024); + fLinkTxField->SetText(buffer); + + snprintf(buffer, sizeof(buffer), B_TRANSLATE("%" B_PRIu64 " KBytes"), + stats.receive.bytes / 1024); + fLinkRxField->SetText(buffer); + return B_OK; } diff --git a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceHardwareView.h b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceHardwareView.h index 7e023b754c..43ddb790f9 100644 --- a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceHardwareView.h +++ b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceHardwareView.h @@ -3,7 +3,7 @@ * Distributed under the terms of the MIT License. * * Authors: - * Alexander von Gluck, kallisti5@unixzen.com + * Alexander von Gluck, kallisti5@unixzen.com * John Scipione, jscipione@gmail.com */ #ifndef INTERFACE_HARDWARE_VIEW_H @@ -31,6 +31,8 @@ public: status_t Save(); private: + status_t Update(); + void _EnableFields(bool enabled); NetworkSettings* fSettings; @@ -38,6 +40,8 @@ private: BStringView* fStatusField; BStringView* fMacAddressField; BStringView* fLinkSpeedField; + BStringView* fLinkTxField; + BStringView* fLinkRxField; }; diff --git a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceWindow.cpp b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceWindow.cpp index 424c8b60ae..38de21a6b7 100644 --- a/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceWindow.cpp +++ b/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceWindow.cpp @@ -104,14 +104,9 @@ InterfaceWindow::_PopulateTabs() fTabHardwareView = new InterfaceHardwareView(frame, fNetworkSettings); fTabView->AddTab(fTabHardwareView, hardwareTab); + hardwareTab->SetLabel(B_TRANSLATE("Interface")); - if (fNetworkSettings->IsEthernet()) - hardwareTab->SetLabel(B_TRANSLATE("Wired")); - else - hardwareTab->SetLabel(B_TRANSLATE("Wirless")); - - for (int index = 0; index < MAX_PROTOCOLS; index++) - { + for (int index = 0; index < MAX_PROTOCOLS; index++) { if (supportedFamilies[index].present) { int inet_id = supportedFamilies[index].inet_id; fTabIPView[inet_id] = new InterfaceAddressView(frame, diff --git a/src/tests/kits/net/preflet/InterfacesAddOn/InterfacesListView.cpp b/src/tests/kits/net/preflet/InterfacesAddOn/InterfacesListView.cpp index 9d94011380..e530e1e567 100644 --- a/src/tests/kits/net/preflet/InterfacesAddOn/InterfacesListView.cpp +++ b/src/tests/kits/net/preflet/InterfacesAddOn/InterfacesListView.cpp @@ -104,7 +104,7 @@ InterfaceListItem::DrawItem(BView* owner, BRect /*bounds*/, bool complete) BRect bounds = list->ItemFrame(list->IndexOf(this)); - rgb_color highColor = list->HighColor(); + //rgb_color highColor = list->HighColor(); rgb_color lowColor = list->LowColor(); if (IsSelected() || complete) { @@ -224,7 +224,7 @@ InterfaceListItem::Update(BView* owner, const BFont* font) fSecondlineOffset = fFirstlineOffset + lineHeight; fThirdlineOffset = fFirstlineOffset + (lineHeight * 2); - SetHeight(max(3 * lineHeight + 4, fIcon->Bounds().Height() + 8)); + SetHeight(std::max(3 * lineHeight + 4, fIcon->Bounds().Height() + 8)); // either to the text height or icon height, whichever is taller } diff --git a/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.h b/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.h index d2b476a332..0ecce147f1 100644 --- a/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.h +++ b/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.h @@ -83,6 +83,9 @@ public: const char* Name() { return fName.String(); } const char* Domain() { return fDomain.String(); } + status_t Stats(ifreq_stats* ptr) + { return fNetworkInterface->GetStats(*ptr); } + bool IsDisabled() { return fDisabled; } bool IsWireless() {