diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 84b2500786..7f3624bfbd 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -98,11 +98,11 @@ SYSTEM_NETWORK_PROTOCOLS = ipv4 tcp udp icmp unix icmp6 ipv6 ; SYSTEM_ADD_ONS_ACCELERANTS = [ FFilterByBuildFeatures x86,x86_64 @{ - vesa.accelerant + vesa.accelerant intel_extreme.accelerant }@ # x86,x86_64 x86 @{ 3dfx.accelerant ati.accelerant matrox.accelerant neomagic.accelerant - nvidia.accelerant intel_810.accelerant intel_extreme.accelerant + nvidia.accelerant intel_810.accelerant radeon.accelerant radeon_hd.accelerant s3.accelerant #via.accelerant vmware.accelerant }@ # x86 @@ -156,10 +156,10 @@ SYSTEM_ADD_ONS_DRIVERS_AUDIO = auich auvia echo3g emuxki hda ice1712 sis7018 ; SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD = ; #cmedia usb_audio ; SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = [ FFilterByBuildFeatures x86,x86_64 @{ - vesa + vesa intel_extreme }@ # x86,x86_64 x86 @{ - ati 3dfx intel_810 intel_extreme matrox neomagic nvidia radeon radeon_hd + ati 3dfx intel_810 matrox neomagic nvidia radeon radeon_hd s3 #via vmware }@ # x86 ] ; @@ -187,7 +187,7 @@ SYSTEM_ADD_ONS_DRIVERS_NET = [ FFilterByBuildFeatures SYSTEM_ADD_ONS_DRIVERS_POWER = [ FFilterByBuildFeatures acpi_button@x86 ] ; SYSTEM_ADD_ONS_BUS_MANAGERS = [ FFilterByBuildFeatures ata@ata pci ps2@x86,x86_64 isa@x86,x86_64 - ide@ide scsi config_manager agp_gart@x86 usb firewire@x86 acpi@x86 + ide@ide scsi config_manager agp_gart@x86,x86_64 usb firewire@x86 acpi@x86 virtio random ] ; SYSTEM_ADD_ONS_FILE_SYSTEMS = bfs btrfs cdda exfat ext2 fat iso9660 nfs nfs4 @@ -216,7 +216,7 @@ for driver in $(SYSTEM_ADD_ONS_DRIVERS_NET) { AddFilesToHaikuImage system add-ons kernel bus_managers : $(SYSTEM_ADD_ONS_BUS_MANAGERS) ; AddFilesToHaikuImage system add-ons kernel busses agp_gart - : intel@x86 ; + : intel@x86,x86_64 ; if $(HAIKU_ATA_STACK) = 1 { AddFilesToHaikuImage system add-ons kernel busses ata diff --git a/build/scripts/build_cross_tools b/build/scripts/build_cross_tools index 9e2fd4edb0..37b7616b85 100755 --- a/build/scripts/build_cross_tools +++ b/build/scripts/build_cross_tools @@ -20,7 +20,7 @@ additionalMakeArgs=$* # additional flags for the binutils build. Should there ever be any other # flags than -jN, we need to handle this differently. -if [ `uname -o` = 'Haiku' ]; then +if [ `uname -s` = 'Haiku' ]; then # force cross-build if building on Haiku: buildhostMachine=i586-pc-haiku_buildhost buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine" diff --git a/build/scripts/build_cross_tools_gcc4 b/build/scripts/build_cross_tools_gcc4 index f9b6023532..2d587720c6 100755 --- a/build/scripts/build_cross_tools_gcc4 +++ b/build/scripts/build_cross_tools_gcc4 @@ -50,7 +50,7 @@ arm-*) ;; esac -if [ `uname -o` = 'Haiku' ]; then +if [ `uname -s` = 'Haiku' ]; then # force cross-build if building on Haiku: buildhostMachine=${haikuMachine}_buildhost buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine" diff --git a/data/catalogs/apps/activitymonitor/fi.catkeys b/data/catalogs/apps/activitymonitor/fi.catkeys index eea09ea3e6..b1bc1b1fb5 100644 --- a/data/catalogs/apps/activitymonitor/fi.catkeys +++ b/data/catalogs/apps/activitymonitor/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-ActivityMonitor 2739021859 +1 finnish x-vnd.Haiku-ActivityMonitor 1211510241 P-faults DataSource P-viat Media nodes DataSource Mediasolmut Threads DataSource Säikeet @@ -6,6 +6,7 @@ Always on top ActivityWindow Aina päällimmäisenä Add graph ActivityWindow Lisää kuvaaja Teams DataSource Ryhmät Hide legend ActivityView Piilota merkin selitys +MiB DataSource mebitavua Network send DataSource Verkkolähetys CPU usage (combined) DataSource Suoritinkäyttö (yhdistetty) CPU DataSource Suoritin @@ -26,12 +27,14 @@ Update time interval: SettingsWindow Päivitä aikaväli: TX DataSource Shorter version for Sending Läh. Quit ActivityWindow Poistu Block cache memory DataSource Lohkovälimuisti +%.1f KiB/s DataSource %.1f kibitavua/s Remove graph ActivityView Poista kuvaaja %lld sec. SettingsWindow %lld s %lld ms SettingsWindow %lld ms CPU usage DataSource Suoritinkäyttö Raw clipboard DataSource Raakadataleikepöytä Sems DataSource Opastimet +%.1f MiB DataSource %.1f Mebitavua ActivityMonitor System name Aktiviteettivalvonta Running applications DataSource Suoritetaan sovelluksia Semaphores DataSource Opastimet diff --git a/data/catalogs/apps/icon-o-matic/fr.catkeys b/data/catalogs/apps/icon-o-matic/fr.catkeys index 6383f582f2..806631486e 100644 --- a/data/catalogs/apps/icon-o-matic/fr.catkeys +++ b/data/catalogs/apps/icon-o-matic/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.haiku-icon_o_matic 605140404 +1 french x-vnd.haiku-icon_o_matic 806315965 Select All Icon-O-Matic-PathManipulator Sélectionner tout Add Style Icon-O-Matic-AddStylesCmd Ajouter un style Color (#%02x%02x%02x) Style name after dropping a color Couleur (#%02x%02x%02x) @@ -67,6 +67,7 @@ Contour Transformation Contour Perspective Transformation Perspective Move Transformer Icon-O-Matic-MoveTransformersCmd Déplacer la Transformation Opacity Icon-O-Matic-PropertyNames Opacité +Add with path Icon-O-Matic-ShapesList Ajouter avec un chemin Gradient type Icon-O-Matic-StyleTypes Type de dégradé Icon-O-Matic System name Icon-O-Matic Cancel Icon-O-Matic-Menu-Settings Annuler @@ -79,6 +80,7 @@ META:ICON Attribute Icon-O-Matic-SavePanel Attribut META:ICON Translation Y Icon-O-Matic-PropertyNames Translation en Y Rotate Icon-O-Matic-TransformationBoxStates Pivoter Remove Transformer Icon-O-Matic-RemoveTransformersCmd Supprimer une transformation +Rotate Path Indices Icon-O-Matic-RotatePathIndiciesCmd Rotation des indices de chemin Add Transformer Icon-O-Matic-AddTransformersCmd Ajouter une transformation Remove Icon-O-Matic-PathsList Enlever Nudge Control Point Icon-O-Matic-NudgePointsCommand Déplacer le point de contrôle diff --git a/data/catalogs/kits/mail/fi.catkeys b/data/catalogs/kits/mail/fi.catkeys index da29589bc9..994a53ba36 100644 --- a/data/catalogs/kits/mail/fi.catkeys +++ b/data/catalogs/kits/mail/fi.catkeys @@ -1,7 +1,8 @@ -1 finnish x-vnd.Haiku-libmail 161731481 +1 finnish x-vnd.Haiku-libmail 4037525365 Partially download messages larger than ProtocolConfigView Osittain ladatut viestit suurempia kuin Password: ProtocolConfigView Salasana: Remove mail from server when deleted ProtocolConfigView Poista sähköposti palvelimelta poistettaessa +KiB ProtocolConfigView kibitavua Mail server: ProtocolConfigView Sähköpostipalvelin: Select… MailKit Valitse... Connection type: ProtocolConfigView Yhteystyyppi: diff --git a/data/catalogs/preferences/screensaver/be.catkeys b/data/catalogs/preferences/screensaver/be.catkeys index 48c4f84ac0..3925c11a48 100644 --- a/data/catalogs/preferences/screensaver/be.catkeys +++ b/data/catalogs/preferences/screensaver/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-ScreenSaver 3630119516 +1 belarusian x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Не ўдалося загрузіць захавальнік экрана 30 seconds ScreenSaver 30 секунд Start screensaver ScreenSaver Запусціць захавальнік @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Кіраванне ScreenSaver System name Захавальнік Экрана Test ScreenSaver Тэст General ScreenSaver Агульныя +Fade now when mouse is here ScreenSaver Зацямняць перасунуўшы указальнік мышы сюды Enable screensaver ScreenSaver Уключыць захавальнік +Don't fade when mouse is here ScreenSaver Не зацямняць калі указальнік мышы знаходзіцца тут Cancel ScreenSaver Адмена Turn off screen ScreenSaver Выключыць экран No options available ScreenSaver Ніякія опцыі недаступныя diff --git a/data/catalogs/preferences/screensaver/de.catkeys b/data/catalogs/preferences/screensaver/de.catkeys index b039065d8a..a576ac2053 100644 --- a/data/catalogs/preferences/screensaver/de.catkeys +++ b/data/catalogs/preferences/screensaver/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-ScreenSaver 3630119516 +1 german x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Bildschirmschoner konnte nicht geladen werden. 30 seconds ScreenSaver 30 Sekunden Start screensaver ScreenSaver Bildschirmschoner starten @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Stromsparfunktione ScreenSaver System name Bildschirmschoner Test ScreenSaver Test General ScreenSaver Allgemein +Fade now when mouse is here ScreenSaver Sofort starten, wenn Maus in diesem Eck Enable screensaver ScreenSaver Bildschirmschoner aktivieren +Don't fade when mouse is here ScreenSaver Nicht starten, wenn Maus in diesem Eck Cancel ScreenSaver Abbrechen Turn off screen ScreenSaver Bildschirm ausschalten No options available ScreenSaver Keine Optionen verfügbar diff --git a/data/catalogs/preferences/screensaver/fi.catkeys b/data/catalogs/preferences/screensaver/fi.catkeys index 3aa51a0d98..f7a7179924 100644 --- a/data/catalogs/preferences/screensaver/fi.catkeys +++ b/data/catalogs/preferences/screensaver/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-ScreenSaver 3630119516 +1 finnish x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Näytönsäästäjän lataus epäonnistui 30 seconds ScreenSaver 30 sekuntia Start screensaver ScreenSaver Käynnistä näytönsäästäjä @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Näytön jännites ScreenSaver System name Näytönsäästäjäasetukset Test ScreenSaver Testaa General ScreenSaver Yleinen +Fade now when mouse is here ScreenSaver Häivytä nyt kun hiiren kohdistin on tässä Enable screensaver ScreenSaver Ota käyttöön näytönsäästäjä +Don't fade when mouse is here ScreenSaver Älä häivytä, kun hiiren kohdistin on tässä Cancel ScreenSaver Peru Turn off screen ScreenSaver Käännä näyttö pois päältä No options available ScreenSaver Valitsimia ei ole käytettävissä diff --git a/data/catalogs/preferences/screensaver/fr.catkeys b/data/catalogs/preferences/screensaver/fr.catkeys index 46ae0944ad..630beaf17a 100644 --- a/data/catalogs/preferences/screensaver/fr.catkeys +++ b/data/catalogs/preferences/screensaver/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-ScreenSaver 3630119516 +1 french x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Impossible de charger l'économiseur d'écran 30 seconds ScreenSaver 30 secondes Start screensaver ScreenSaver Démarrer l'économiseur @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Le système d'éco ScreenSaver System name Économiseur d'écran Test ScreenSaver Tester General ScreenSaver Général +Fade now when mouse is here ScreenSaver Estomper maintenant lorsque la souris est ici Enable screensaver ScreenSaver Activer l'économiseur +Don't fade when mouse is here ScreenSaver Ne pas estomper lorsque la souris est ici Cancel ScreenSaver Annuler Turn off screen ScreenSaver Extinction de l'écran No options available ScreenSaver Aucune option disponible diff --git a/data/catalogs/preferences/screensaver/hu.catkeys b/data/catalogs/preferences/screensaver/hu.catkeys index ebb2c4e37f..a41a110074 100644 --- a/data/catalogs/preferences/screensaver/hu.catkeys +++ b/data/catalogs/preferences/screensaver/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Haiku-ScreenSaver 3630119516 +1 hungarian x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver A képernyővédő betöltése sikertelen 30 seconds ScreenSaver 30 másodperc Start screensaver ScreenSaver Képernyővédő indítása @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver A kijelző energia ScreenSaver System name Képernyővédő Test ScreenSaver Próba General ScreenSaver Általános +Fade now when mouse is here ScreenSaver Bekapcsolás, ha az egér itt van Enable screensaver ScreenSaver Képernyővédő engedélyezése +Don't fade when mouse is here ScreenSaver Ne kapcsoljon be, ha az egér itt van Cancel ScreenSaver Mégse Turn off screen ScreenSaver Képernyő kikapcsolása No options available ScreenSaver Nincsenek elérhető beállítások diff --git a/data/catalogs/preferences/screensaver/ja.catkeys b/data/catalogs/preferences/screensaver/ja.catkeys index c247d6b182..c1a0c1d5fa 100644 --- a/data/catalogs/preferences/screensaver/ja.catkeys +++ b/data/catalogs/preferences/screensaver/ja.catkeys @@ -1,4 +1,4 @@ -1 japanese x-vnd.Haiku-ScreenSaver 3630119516 +1 japanese x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver スクリーンセーバーを実行できませんでした 30 seconds ScreenSaver 30 秒 Start screensaver ScreenSaver スクリーンセーバーを開始 @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver DPMS (Display Powe ScreenSaver System name スクリーンセーバー Test ScreenSaver テスト General ScreenSaver 一般 +Fade now when mouse is here ScreenSaver マウスが指定の場所にあるときに画面を消す Enable screensaver ScreenSaver スクリーンセーバーを有効にする +Don't fade when mouse is here ScreenSaver マウスが指定の場所にあるとき画面を消さない Cancel ScreenSaver 取り消し Turn off screen ScreenSaver 画面を消す No options available ScreenSaver 設定がありません diff --git a/docs/develop/ports/arm/todo.txt b/docs/develop/ports/arm/todo.txt index e49b6c8aa5..9e73bea4ea 100644 --- a/docs/develop/ports/arm/todo.txt +++ b/docs/develop/ports/arm/todo.txt @@ -1,3 +1,8 @@ +* Determine how to handle atomic functions on ARM. + GCC inlines are not supported, since the instructionset is ill-equiped for + this on older (pre-ARMv7) architectures. We possibly have to do something + similar to the linux kernel helper functions for this.... + * Figure out how to get page flags (modified/accessed) and implement it ;) use unmapped/read-only mappings to trigger soft faults for tracking used/modified flags for ARMv5 and ARMv6 diff --git a/headers/posix/limits.h b/headers/posix/limits.h index e010cf3ea2..cdd95283f8 100644 --- a/headers/posix/limits.h +++ b/headers/posix/limits.h @@ -43,7 +43,7 @@ #define PATH_MAX (1024) #define PIPE_MAX (512) #define PTHREAD_KEYS_MAX 256 -#define PTHREAD_STACK_MIN 4096 +#define PTHREAD_STACK_MIN (2 * PAGE_SIZE) #define SSIZE_MAX __HAIKU_SADDR_MAX #define TTY_NAME_MAX (256) #define TZNAME_MAX (32) diff --git a/headers/posix/net/if_media.h b/headers/posix/net/if_media.h index e0fdc4e76d..ca67cf629d 100644 --- a/headers/posix/net/if_media.h +++ b/headers/posix/net/if_media.h @@ -31,6 +31,7 @@ #define IFM_100_TX 6 /* 100Base-TX - RJ45 */ #define IFM_1000_T 16 /* 1000Base-T - RJ45 */ #define IFM_1000_SX 18 /* 1000Base-SX - Fiber Optic */ +#define IFM_10G_T 22 /* 10GBase-T - RJ45 */ /* General options */ diff --git a/headers/private/interface/ColumnListView.h b/headers/private/interface/ColumnListView.h index 027154b98b..f262b09f47 100644 --- a/headers/private/interface/ColumnListView.h +++ b/headers/private/interface/ColumnListView.h @@ -135,6 +135,8 @@ public: bool IsExpanded() const; bool IsSelected() const; + void Invalidate(); + private: // Blows up into the debugger if the validation fails. void ValidateFields() const; @@ -332,6 +334,8 @@ public: parentRow1 = NULL, BRow* parentRow2 = NULL); void Clear(); + void InvalidateRow(BRow* row); + // Appearance (DEPRECATED) void GetFont(BFont* font) const { BView::GetFont(font); } diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h index 3d7a3c1654..c2cc881206 100644 --- a/headers/private/system/thread_defs.h +++ b/headers/private/system/thread_defs.h @@ -13,10 +13,10 @@ /** Size of the stack given to teams in user space */ #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 (8 * 1024) // 8 kB -#define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB +#define MIN_USER_STACK_SIZE (2 * B_PAGE_SIZE) // 8 kB +#define MAX_USER_STACK_SIZE (4096 * B_PAGE_SIZE) // 16 MB +#define USER_MAIN_THREAD_STACK_SIZE MAX_USER_STACK_SIZE +#define USER_STACK_SIZE (64 * B_PAGE_SIZE) // 256 kB // The type of object a thread blocks on (thread::wait::type, set by diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index 1ae8696859..7ef7269bd8 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -141,9 +141,11 @@ init_common(int device, bool isClone) // The overlay registers, hardware status, and cursor memory share // a single area with the shared_info - gInfo->overlay_registers = (struct overlay_registers*) - (gInfo->shared_info->graphics_memory - + gInfo->shared_info->overlay_offset); + if (gInfo->shared_info->overlay_offset != 0) { + gInfo->overlay_registers = (struct overlay_registers*) + (gInfo->shared_info->graphics_memory + + gInfo->shared_info->overlay_offset); + } if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_96x)) { // allocate some extra memory for the 3D context diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 4e87f10f78..00182b8040 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -431,7 +431,10 @@ retrieve_current_mode(display_mode& mode, uint32 pllRegister) mode.h_display_start = 0; mode.v_display_start = 0; mode.flags = B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS - | B_DPMS | B_SUPPORTS_OVERLAYS; + | B_DPMS; + if (gInfo->overlay_registers != NULL) { + mode.flags |= B_SUPPORTS_OVERLAYS; + } } diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp index e778ffcbac..b8ff560260 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp @@ -1174,6 +1174,57 @@ hda_codec_switch_init(hda_audio_group* audioGroup) } +static void +hda_codec_check_sense(hda_codec* codec, bool disable) +{ + hda_audio_group* audioGroup = codec->audio_groups[0]; + + for (uint32 i = 0; i < audioGroup->widget_count; i++) { + hda_widget& widget = audioGroup->widgets[i]; + + if (widget.type != WT_PIN_COMPLEX + || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities) + || CONF_DEFAULT_DEVICE(widget.d.pin.config) + != PIN_DEV_HEAD_PHONE_OUT) + continue; + + corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, + VID_GET_PINSENSE, 0); + uint32 response; + hda_send_verbs(audioGroup->codec, &verb, &response, 1); + disable = response & PIN_SENSE_PRESENCE_DETECT; + TRACE("hda: sensed pin widget %ld, %d\n", widget.node_id, disable); + + uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget, + true); + verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, + VID_SET_PIN_WIDGET_CONTROL, disable ? ctrl : 0); + hda_send_verbs(audioGroup->codec, &verb, NULL, 1); + break; + } + + for (uint32 i = 0; i < audioGroup->widget_count; i++) { + hda_widget& widget = audioGroup->widgets[i]; + + if (widget.type != WT_PIN_COMPLEX + || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities)) + continue; + + int device = CONF_DEFAULT_DEVICE(widget.d.pin.config); + if (device != PIN_DEV_AUX + && device != PIN_DEV_SPEAKER + && device != PIN_DEV_LINE_OUT) + continue; + + uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget, + true); + corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, + VID_SET_PIN_WIDGET_CONTROL, disable ? 0 : ctrl); + hda_send_verbs(audioGroup->codec, &verb, NULL, 1); + } +} + + static status_t hda_codec_switch_handler(hda_codec* codec) { @@ -1182,53 +1233,8 @@ hda_codec_switch_handler(hda_codec* codec) codec->unsol_response_read %= MAX_CODEC_UNSOL_RESPONSES; bool disable = response & 1; - hda_audio_group* audioGroup = codec->audio_groups[0]; - - for (uint32 i = 0; i < audioGroup->widget_count; i++) { - hda_widget& widget = audioGroup->widgets[i]; - - if (widget.type != WT_PIN_COMPLEX - || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities) - || CONF_DEFAULT_DEVICE(widget.d.pin.config) - != PIN_DEV_HEAD_PHONE_OUT) - continue; - - corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, - VID_GET_PINSENSE, 0); - uint32 response; - hda_send_verbs(audioGroup->codec, &verb, &response, 1); - disable = response & PIN_SENSE_PRESENCE_DETECT; - TRACE("hda: sensed pin widget %ld, %d\n", widget.node_id, disable); - - uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget, - true); - verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, - VID_SET_PIN_WIDGET_CONTROL, disable ? ctrl : 0); - hda_send_verbs(audioGroup->codec, &verb, NULL, 1); - break; - } - - for (uint32 i = 0; i < audioGroup->widget_count; i++) { - hda_widget& widget = audioGroup->widgets[i]; - - if (widget.type != WT_PIN_COMPLEX - || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities)) - continue; - - int device = CONF_DEFAULT_DEVICE(widget.d.pin.config); - if (device != PIN_DEV_AUX - && device != PIN_DEV_SPEAKER - && device != PIN_DEV_LINE_OUT) - continue; - - uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget, - true); - corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, - VID_SET_PIN_WIDGET_CONTROL, disable ? 0 : ctrl); - hda_send_verbs(audioGroup->codec, &verb, NULL, 1); - } + hda_codec_check_sense(codec, disable); } - return B_OK; } @@ -1521,6 +1527,8 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress) } } + hda_codec_check_sense(codec, false); + codec->unsol_response_thread = spawn_kernel_thread( (status_t(*)(void*))hda_codec_switch_handler, "hda_codec_unsol_thread", B_LOW_PRIORITY, codec); diff --git a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp index 37b9186c1e..1fd7be7e40 100644 --- a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp +++ b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp @@ -31,7 +31,10 @@ #define NORFLASH_ADDR 0x00000000 +#define SIZE_IN_BLOCKS 256 +/* Hide the start of NOR since U-Boot lives there */ +#define HIDDEN_BLOCKS 2 struct nor_driver_info { device_node *node; @@ -54,7 +57,7 @@ nor_init_device(void *_info, void **_cookie) info->mapped = NULL; info->blocksize = 128 * 1024; - info->totalsize = info->blocksize * 256; + info->totalsize = (SIZE_IN_BLOCKS - HIDDEN_BLOCKS) * info->blocksize; info->id = map_physical_memory("NORFlash", NORFLASH_ADDR, info->totalsize, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &info->mapped); if (info->id < 0) @@ -139,6 +142,8 @@ nor_read(void *_cookie, off_t position, void *data, size_t *numbytes) nor_driver_info *info = (nor_driver_info*)_cookie; TRACE("read(%Ld,%lu)\n", position, *numbytes); + position += HIDDEN_BLOCKS * info->blocksize; + if (position + *numbytes > info->totalsize) *numbytes = info->totalsize - (position + *numbytes); @@ -160,8 +165,16 @@ nor_write(void *_cookie, off_t position, const void *data, size_t *numbytes) static float nor_supports_device(device_node *parent) { + const char *bus; TRACE("supports_device\n"); - return 0.6; + + if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) + return B_ERROR; + + if (strcmp(bus, "generic")) + return 0.0; + + return 1.0; } diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index ddc02b4898..ff03f98071 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -267,8 +267,8 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, uint32 logicalBlockAddress, uint16 transferLength, void *data, size_t *dataLength, bool directionIn) { - TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %lu; tlen: %u; data: " - "%p; dlen: %p (%lu); in: %c\n", + TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %" B_PRIu32 + "; tlen: %u; data: %p; dlen: %p (%lu); in: %c\n", lun->logical_unit_number, operation, opLength, logicalBlockAddress, transferLength, data, dataLength, dataLength ? *dataLength : 0, directionIn ? 'y' : 'n'); @@ -487,7 +487,7 @@ usb_disk_request_sense(device_lun *lun) parameter.additional_sense_code_qualifier); lun->media_present = false; usb_disk_reset_capacity(lun); - return B_DEV_NO_MEDIA; + return B_DEV_NOT_READY; case SCSI_SENSE_KEY_DATA_PROTECT: TRACE_ALWAYS("request_sense: write protected\n"); @@ -691,7 +691,7 @@ usb_disk_callback(void *cookie, status_t status, void *data, static status_t usb_disk_device_added(usb_device newDevice, void **cookie) { - TRACE("device_added(0x%08lx)\n", newDevice); + TRACE("device_added(0x%08" B_PRIx32 ")\n", newDevice); disk_device *device = (disk_device *)malloc(sizeof(disk_device)); device->device = newDevice; device->removed = false; @@ -856,7 +856,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie) sprintf(device->luns[i]->name, DEVICE_NAME, device->device_number, i); mutex_unlock(&gDeviceListLock); - TRACE("new device: 0x%08lx\n", (uint32)device); + TRACE("new device: 0x%p\n", device); *cookie = (void *)device; return B_OK; } @@ -865,7 +865,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie) static status_t usb_disk_device_removed(void *cookie) { - TRACE("device_removed(0x%08lx)\n", (uint32)cookie); + TRACE("device_removed(0x%p)\n", cookie); disk_device *device = (disk_device *)cookie; mutex_lock(&gDeviceListLock); @@ -963,7 +963,7 @@ usb_disk_prepare_partial_buffer(device_lun *lun, off_t position, size_t length, return result; } - off_t offset = position - (blockPosition * lun->block_size); + off_t offset = position - (off_t)blockPosition * lun->block_size; partialBuffer = (uint8 *)blockBuffer + offset; return B_OK; } @@ -1096,7 +1096,8 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) case B_GET_MEDIA_STATUS: { *(status_t *)buffer = usb_disk_test_unit_ready(lun); - TRACE("B_GET_MEDIA_STATUS: 0x%08lx\n", *(status_t *)buffer); + TRACE("B_GET_MEDIA_STATUS: 0x%08" B_PRIx32 "\n", + *(status_t *)buffer); result = B_OK; break; } @@ -1117,8 +1118,9 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) geometry.removable = lun->removable; geometry.read_only = lun->write_protected; geometry.write_once = lun->device_type == B_WORM; - TRACE("B_GET_GEOMETRY: %ld sectors at %ld bytes per sector\n", - geometry.cylinder_count, geometry.bytes_per_sector); + TRACE("B_GET_GEOMETRY: %" B_PRId32 " sectors at %" B_PRId32 + " bytes per sector\n", geometry.cylinder_count, + geometry.bytes_per_sector); result = user_memcpy(buffer, &geometry, sizeof(device_geometry)); break; } @@ -1212,7 +1214,7 @@ usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length) if (buffer == NULL || length == NULL) return B_BAD_VALUE; - TRACE("read(%lld, %ld)\n", position, *length); + TRACE("read(%" B_PRIdOFF ", %ld)\n", position, *length); device_lun *lun = (device_lun *)cookie; disk_device *device = lun->device; mutex_lock(&device->lock); @@ -1260,7 +1262,7 @@ usb_disk_write(void *cookie, off_t position, const void *buffer, if (buffer == NULL || length == NULL) return B_BAD_VALUE; - TRACE("write(%lld, %ld)\n", position, *length); + TRACE("write(%" B_PRIdOFF", %ld)\n", position, *length); device_lun *lun = (device_lun *)cookie; disk_device *device = lun->device; mutex_lock(&device->lock); diff --git a/src/add-ons/kernel/drivers/network/Jamfile b/src/add-ons/kernel/drivers/network/Jamfile index 2940c7eb1e..224ba0c195 100644 --- a/src/add-ons/kernel/drivers/network/Jamfile +++ b/src/add-ons/kernel/drivers/network/Jamfile @@ -9,6 +9,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network usb_asix ; SubInclude HAIKU_TOP src add-ons kernel drivers network usb_davicom ; SubInclude HAIKU_TOP src add-ons kernel drivers network usb_ecm ; SubInclude HAIKU_TOP src add-ons kernel drivers network via_rhine ; +SubInclude HAIKU_TOP src add-ons kernel drivers network virtio ; SubInclude HAIKU_TOP src add-ons kernel drivers network vlance ; SubInclude HAIKU_TOP src add-ons kernel drivers network wb840 ; diff --git a/src/add-ons/kernel/drivers/network/virtio/Jamfile b/src/add-ons/kernel/drivers/network/virtio/Jamfile new file mode 100644 index 0000000000..f8131115f2 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/virtio/Jamfile @@ -0,0 +1,8 @@ +SubDir HAIKU_TOP src add-ons kernel drivers network virtio ; + +UsePrivateKernelHeaders ; +UsePrivateHeaders drivers net virtio ; + +KernelAddon virtio_net : + virtio_net.cpp +; diff --git a/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp b/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp new file mode 100644 index 0000000000..4a6a66e3a5 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp @@ -0,0 +1,462 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include +#include + +#include +#include + +#include "ether_driver.h" +#define ETHER_ADDR_LEN ETHER_ADDRESS_LENGTH +#include "virtio_net.h" + +#define MAX_FRAME_SIZE 1536 + +#define VIRTIO_NET_DRIVER_MODULE_NAME "drivers/network/virtio_net/driver_v1" +#define VIRTIO_NET_DEVICE_MODULE_NAME "drivers/network/virtio_net/device_v1" +#define VIRTIO_NET_DEVICE_ID_GENERATOR "virtio_net/device_id" + + +typedef struct { + device_node* node; + ::virtio_device virtio_device; + virtio_device_interface* virtio; + + uint32 features; + + uint32 pairs_count; + ::virtio_queue* receive_queues; + ::virtio_queue* send_queues; + + + bool nonblocking; + uint32 maxframesize; + uint8 macaddr[6]; + +} virtio_net_driver_info; + + +typedef struct { + virtio_net_driver_info* info; +} virtio_net_handle; + + +#include +#include +#include + +#include + + +#define TRACE_VIRTIO_NET +#ifdef TRACE_VIRTIO_NET +# define TRACE(x...) dprintf("virtio_net: " x) +#else +# define TRACE(x...) ; +#endif +#define ERROR(x...) dprintf("\33[33mvirtio_net:\33[0m " x) +#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) + + +static device_manager_info* sDeviceManager; + + +const char * +get_feature_name(uint32 feature) +{ + switch (feature) { + case VIRTIO_NET_F_CSUM: + return "host checksum"; + case VIRTIO_NET_F_GUEST_CSUM: + return "guest checksum"; + case VIRTIO_NET_F_MAC: + return "macaddress"; + case VIRTIO_NET_F_GSO: + return "host allgso"; + case VIRTIO_NET_F_GUEST_TSO4: + return "guest tso4"; + case VIRTIO_NET_F_GUEST_TSO6: + return "guest tso6"; + case VIRTIO_NET_F_GUEST_ECN: + return "guest tso6+ecn"; + case VIRTIO_NET_F_GUEST_UFO: + return "guest ufo"; + case VIRTIO_NET_F_HOST_TSO4: + return "host tso4"; + case VIRTIO_NET_F_HOST_TSO6: + return "host tso6"; + case VIRTIO_NET_F_HOST_ECN: + return "host tso6+ecn"; + case VIRTIO_NET_F_HOST_UFO: + return "host UFO"; + case VIRTIO_NET_F_MRG_RXBUF: + return "host mergerxbuffers"; + case VIRTIO_NET_F_STATUS: + return "status"; + case VIRTIO_NET_F_CTRL_VQ: + return "control vq"; + case VIRTIO_NET_F_CTRL_RX: + return "rx mode"; + case VIRTIO_NET_F_CTRL_VLAN: + return "vlan filter"; + case VIRTIO_NET_F_CTRL_RX_EXTRA: + return "rx mode extra"; + case VIRTIO_NET_F_GUEST_ANNOUNCE: + return "guest announce"; + case VIRTIO_NET_F_MQ: + return "multiqueue"; + case VIRTIO_NET_F_CTRL_MAC_ADDR: + return "set macaddress"; + } + return NULL; +} + + +// #pragma mark - device module API + + +static status_t +virtio_net_init_device(void* _info, void** _cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_info; + + device_node* parent = sDeviceManager->get_parent_node(info->node); + sDeviceManager->get_driver(parent, (driver_module_info **)&info->virtio, + (void **)&info->virtio_device); + sDeviceManager->put_node(parent); + + info->virtio->negociate_features(info->virtio_device, + 0 /* */, &info->features, &get_feature_name); + + if ((info->features & VIRTIO_NET_F_MQ) != 0 + && info->virtio->read_device_config(info->virtio_device, + offsetof(struct virtio_net_config, max_virtqueue_pairs), + &info->pairs_count, sizeof(info->pairs_count)) == B_OK) { + system_info sysinfo; + if (get_system_info(&sysinfo) == B_OK + && info->pairs_count > sysinfo.cpu_count) { + info->pairs_count = sysinfo.cpu_count; + } + } else + info->pairs_count = 1; + + // TODO read config + + uint32 queueCount = info->pairs_count * 2; + if ((info->features & VIRTIO_NET_F_CTRL_VQ) != 0) + queueCount++; + ::virtio_queue virtioQueues[queueCount]; + status_t status = info->virtio->alloc_queues(info->virtio_device, queueCount, + virtioQueues); + if (status != B_OK) { + ERROR("queue allocation failed (%s)\n", strerror(status)); + return status; + } + + info->receive_queues = new(std::nothrow) virtio_queue[info->pairs_count]; + info->send_queues = new(std::nothrow) virtio_queue[info->pairs_count]; + if (info->receive_queues == NULL || info->receive_queues == NULL) + return B_NO_MEMORY; + for (uint32 i = 0; i < info->pairs_count; i++) { + info->receive_queues[i] = virtioQueues[i * 2]; + info->send_queues[i] = virtioQueues[i * 2 + 1]; + } + + // TODO setup interrupts + + *_cookie = info; + return B_OK; +} + + +static void +virtio_net_uninit_device(void* _cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_cookie; +} + + +static status_t +virtio_net_open(void* _info, const char* path, int openMode, void** _cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_info; + + virtio_net_handle* handle = (virtio_net_handle*)malloc( + sizeof(virtio_net_handle)); + if (handle == NULL) + return B_NO_MEMORY; + + info->nonblocking = (openMode & O_NONBLOCK) != 0; + info->maxframesize = MAX_FRAME_SIZE; + handle->info = info; + + if ((info->features & VIRTIO_NET_F_MAC) != 0) { + info->virtio->read_device_config(info->virtio_device, + offsetof(struct virtio_net_config, mac), + &info->macaddr, sizeof(info->macaddr)); + } + + *_cookie = handle; + return B_OK; +} + + +static status_t +virtio_net_close(void* cookie) +{ + //virtio_net_handle* handle = (virtio_net_handle*)cookie; + CALLED(); + + return B_OK; +} + + +static status_t +virtio_net_free(void* cookie) +{ + CALLED(); + virtio_net_handle* handle = (virtio_net_handle*)cookie; + + free(handle); + return B_OK; +} + + +static status_t +virtio_net_read(void* cookie, off_t pos, void* buffer, size_t* _length) +{ + CALLED(); + virtio_net_handle* handle = (virtio_net_handle*)cookie; + // TODO implement + return B_ERROR; +} + + +static status_t +virtio_net_write(void* cookie, off_t pos, const void* buffer, + size_t* _length) +{ + CALLED(); + virtio_net_handle* handle = (virtio_net_handle*)cookie; + // TODO implement + return B_ERROR; +} + + +static status_t +virtio_net_ioctl(void* cookie, uint32 op, void* buffer, size_t length) +{ + CALLED(); + virtio_net_handle* handle = (virtio_net_handle*)cookie; + virtio_net_driver_info* info = handle->info; + + TRACE("ioctl(op = %lx)\n", op); + + switch (op) { + case ETHER_GETADDR: + TRACE("ioctl: get macaddr\n"); + memcpy(buffer, &info->macaddr, sizeof(info->macaddr)); + return B_OK; + + case ETHER_INIT: + TRACE("ioctl: init\n"); + return B_OK; + + case ETHER_GETFRAMESIZE: + TRACE("ioctl: get frame size\n"); + *(uint32*)buffer = info->maxframesize; + return B_OK; + + case ETHER_SETPROMISC: + TRACE("ioctl: set promisc\n"); + break; + + case ETHER_NONBLOCK: + info->nonblocking = *(int32 *)buffer == 0; + TRACE("ioctl: non blocking ? %s\n", info->nonblocking ? "yes" : "no"); + return B_OK; + + case ETHER_ADDMULTI: + TRACE("ioctl: add multicast\n"); + break; + + case ETHER_GET_LINK_STATE: + { + TRACE("ioctl: get link state\n"); + ether_link_state_t state; + uint16 status = VIRTIO_NET_S_LINK_UP; + if ((info->features & VIRTIO_NET_F_STATUS) != 0) { + info->virtio->read_device_config(info->virtio_device, + offsetof(struct virtio_net_config, status), + &status, sizeof(status)); + } + state.media = ((status & VIRTIO_NET_S_LINK_UP) != 0 ? IFM_ACTIVE : 0) + | IFM_ETHER | IFM_FULL_DUPLEX | IFM_10G_T; + state.speed = 10000000000ULL; + state.quality = 1000; + + return user_memcpy(buffer, &state, sizeof(ether_link_state_t)); + } + + default: + ERROR("ioctl: unknown message %" B_PRIx32 "\n", op); + break; + } + + + return B_DEV_INVALID_IOCTL; +} + + +// #pragma mark - driver module API + + +static float +virtio_net_supports_device(device_node *parent) +{ + CALLED(); + const char *bus; + uint16 deviceType; + + // make sure parent is really the Virtio bus manager + if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) + return -1; + + if (strcmp(bus, "virtio")) + return 0.0; + + // check whether it's really a Direct Access Device + if (sDeviceManager->get_attr_uint16(parent, VIRTIO_DEVICE_TYPE_ITEM, + &deviceType, true) != B_OK || deviceType != VIRTIO_DEVICE_ID_NETWORK) + return 0.0; + + TRACE("Virtio network device found!\n"); + + return 0.6; +} + + +static status_t +virtio_net_register_device(device_node *node) +{ + CALLED(); + + // ready to register + device_attr attrs[] = { + { NULL } + }; + + return sDeviceManager->register_node(node, VIRTIO_NET_DRIVER_MODULE_NAME, + attrs, NULL, NULL); +} + + +static status_t +virtio_net_init_driver(device_node *node, void **cookie) +{ + CALLED(); + + virtio_net_driver_info* info = (virtio_net_driver_info*)malloc( + sizeof(virtio_net_driver_info)); + if (info == NULL) + return B_NO_MEMORY; + + memset(info, 0, sizeof(*info)); + + info->node = node; + + *cookie = info; + return B_OK; +} + + +static void +virtio_net_uninit_driver(void *_cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_cookie; + free(info); +} + + +static status_t +virtio_net_register_child_devices(void* _cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_cookie; + status_t status; + + int32 id = sDeviceManager->create_id(VIRTIO_NET_DEVICE_ID_GENERATOR); + if (id < 0) + return id; + + char name[64]; + snprintf(name, sizeof(name), "net/virtio/%" B_PRId32, + id); + + status = sDeviceManager->publish_device(info->node, name, + VIRTIO_NET_DEVICE_MODULE_NAME); + + return status; +} + + +// #pragma mark - + + +module_dependency module_dependencies[] = { + {B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager}, + {} +}; + +struct device_module_info sVirtioNetDevice = { + { + VIRTIO_NET_DEVICE_MODULE_NAME, + 0, + NULL + }, + + virtio_net_init_device, + virtio_net_uninit_device, + NULL, // remove, + + virtio_net_open, + virtio_net_close, + virtio_net_free, + virtio_net_read, + virtio_net_write, + NULL, // io + virtio_net_ioctl, + + NULL, // select + NULL, // deselect +}; + +struct driver_module_info sVirtioNetDriver = { + { + VIRTIO_NET_DRIVER_MODULE_NAME, + 0, + NULL + }, + + virtio_net_supports_device, + virtio_net_register_device, + virtio_net_init_driver, + virtio_net_uninit_driver, + virtio_net_register_child_devices, + NULL, // rescan + NULL, // removed +}; + +module_info* modules[] = { + (module_info*)&sVirtioNetDriver, + (module_info*)&sVirtioNetDevice, + NULL +}; diff --git a/src/add-ons/kernel/drivers/network/virtio/virtio_net.h b/src/add-ons/kernel/drivers/network/virtio/virtio_net.h new file mode 100644 index 0000000000..315b730006 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/virtio/virtio_net.h @@ -0,0 +1,202 @@ +/*- + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _VIRTIO_NET_H +#define _VIRTIO_NET_H + +/* The feature bitmap for virtio net */ +#define VIRTIO_NET_F_CSUM 0x00001 /* Host handles pkts w/ partial csum */ +#define VIRTIO_NET_F_GUEST_CSUM 0x00002 /* Guest handles pkts w/ partial csum*/ +#define VIRTIO_NET_F_MAC 0x00020 /* Host has given MAC address. */ +#define VIRTIO_NET_F_GSO 0x00040 /* Host handles pkts w/ any GSO type */ +#define VIRTIO_NET_F_GUEST_TSO4 0x00080 /* Guest can handle TSOv4 in. */ +#define VIRTIO_NET_F_GUEST_TSO6 0x00100 /* Guest can handle TSOv6 in. */ +#define VIRTIO_NET_F_GUEST_ECN 0x00200 /* Guest can handle TSO[6] w/ ECN in.*/ +#define VIRTIO_NET_F_GUEST_UFO 0x00400 /* Guest can handle UFO in. */ +#define VIRTIO_NET_F_HOST_TSO4 0x00800 /* Host can handle TSOv4 in. */ +#define VIRTIO_NET_F_HOST_TSO6 0x01000 /* Host can handle TSOv6 in. */ +#define VIRTIO_NET_F_HOST_ECN 0x02000 /* Host can handle TSO[6] w/ ECN in. */ +#define VIRTIO_NET_F_HOST_UFO 0x04000 /* Host can handle UFO in. */ +#define VIRTIO_NET_F_MRG_RXBUF 0x08000 /* Host can merge receive buffers. */ +#define VIRTIO_NET_F_STATUS 0x10000 /* virtio_net_config.status available*/ +#define VIRTIO_NET_F_CTRL_VQ 0x20000 /* Control channel available */ +#define VIRTIO_NET_F_CTRL_RX 0x40000 /* Control channel RX mode support */ +#define VIRTIO_NET_F_CTRL_VLAN 0x80000 /* Control channel VLAN filtering */ +#define VIRTIO_NET_F_CTRL_RX_EXTRA 0x100000 /* Extra RX mode control support */ +#define VIRTIO_NET_F_GUEST_ANNOUNCE 0x200000 /* Announce device on network */ +#define VIRTIO_NET_F_MQ 0x400000 /* Device supports RFS */ +#define VIRTIO_NET_F_CTRL_MAC_ADDR 0x800000 /* Set MAC address */ + +#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ + +struct virtio_net_config { + /* The config defining mac address (if VIRTIO_NET_F_MAC) */ + uint8_t mac[ETHER_ADDR_LEN]; + /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */ + uint16_t status; + /* Maximum number of each of transmit and receive queues; + * see VIRTIO_NET_F_MQ and VIRTIO_NET_CTRL_MQ. + * Legal values are between 1 and 0x8000. + */ + uint16_t max_virtqueue_pairs; +} _PACKED; + +/* + * This is the first element of the scatter-gather list. If you don't + * specify GSO or CSUM features, you can simply ignore the header. + */ +struct virtio_net_hdr { +#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* Use csum_start,csum_offset*/ +#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */ + uint8_t flags; +#define VIRTIO_NET_HDR_GSO_NONE 0 /* Not a GSO frame */ +#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */ +#define VIRTIO_NET_HDR_GSO_UDP 3 /* GSO frame, IPv4 UDP (UFO) */ +#define VIRTIO_NET_HDR_GSO_TCPV6 4 /* GSO frame, IPv6 TCP */ +#define VIRTIO_NET_HDR_GSO_ECN 0x80 /* TCP has ECN set */ + uint8_t gso_type; + uint16_t hdr_len; /* Ethernet + IP + tcp/udp hdrs */ + uint16_t gso_size; /* Bytes to append to hdr_len per frame */ + uint16_t csum_start; /* Position to start checksumming from */ + uint16_t csum_offset; /* Offset after that to place checksum */ +}; + +/* + * This is the version of the header to use when the MRG_RXBUF + * feature has been negotiated. + */ +struct virtio_net_hdr_mrg_rxbuf { + struct virtio_net_hdr hdr; + uint16_t num_buffers; /* Number of merged rx buffers */ +}; + +/* + * Control virtqueue data structures + * + * The control virtqueue expects a header in the first sg entry + * and an ack/status response in the last entry. Data for the + * command goes in between. + */ +struct virtio_net_ctrl_hdr { + uint8_t net_class; // was renamed from class for c++ + uint8_t cmd; +} _PACKED; + +#define VIRTIO_NET_OK 0 +#define VIRTIO_NET_ERR 1 + +/* + * Control the RX mode, ie. promiscuous, allmulti, etc... + * All commands require an "out" sg entry containing a 1 byte + * state value, zero = disable, non-zero = enable. Commands + * 0 and 1 are supported with the VIRTIO_NET_F_CTRL_RX feature. + * Commands 2-5 are added with VIRTIO_NET_F_CTRL_RX_EXTRA. + */ +#define VIRTIO_NET_CTRL_RX 0 +#define VIRTIO_NET_CTRL_RX_PROMISC 0 +#define VIRTIO_NET_CTRL_RX_ALLMULTI 1 +#define VIRTIO_NET_CTRL_RX_ALLUNI 2 +#define VIRTIO_NET_CTRL_RX_NOMULTI 3 +#define VIRTIO_NET_CTRL_RX_NOUNI 4 +#define VIRTIO_NET_CTRL_RX_NOBCAST 5 + +/* + * Control the MAC filter table. + * + * The MAC filter table is managed by the hypervisor, the guest should + * assume the size is infinite. Filtering should be considered + * non-perfect, ie. based on hypervisor resources, the guest may + * received packets from sources not specified in the filter list. + * + * In addition to the class/cmd header, the TABLE_SET command requires + * two out scatterlists. Each contains a 4 byte count of entries followed + * by a concatenated byte stream of the ETH_ALEN MAC addresses. The + * first sg list contains unicast addresses, the second is for multicast. + * This functionality is present if the VIRTIO_NET_F_CTRL_RX feature + * is available. + * + * The ADDR_SET command requests one out scatterlist, it contains a + * 6 bytes MAC address. This functionality is present if the + * VIRTIO_NET_F_CTRL_MAC_ADDR feature is available. + */ +struct virtio_net_ctrl_mac { + uint32_t entries; + uint8_t macs[][ETHER_ADDR_LEN]; +} _PACKED; + +#define VIRTIO_NET_CTRL_MAC 1 +#define VIRTIO_NET_CTRL_MAC_TABLE_SET 0 +#define VIRTIO_NET_CTRL_MAC_ADDR_SET 1 + +/* + * Control VLAN filtering + * + * The VLAN filter table is controlled via a simple ADD/DEL interface. + * VLAN IDs not added may be filtered by the hypervisor. Del is the + * opposite of add. Both commands expect an out entry containing a 2 + * byte VLAN ID. VLAN filtering is available with the + * VIRTIO_NET_F_CTRL_VLAN feature bit. + */ +#define VIRTIO_NET_CTRL_VLAN 2 +#define VIRTIO_NET_CTRL_VLAN_ADD 0 +#define VIRTIO_NET_CTRL_VLAN_DEL 1 + +/* + * Control link announce acknowledgement + * + * The command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that + * driver has recevied the notification; device would clear the + * VIRTIO_NET_S_ANNOUNCE bit in the status field after it receives + * this command. + */ +#define VIRTIO_NET_CTRL_ANNOUNCE 3 +#define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0 + +/* + * Control Receive Flow Steering + * + * The command VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET enables Receive Flow + * Steering, specifying the number of the transmit and receive queues + * that will be used. After the command is consumed and acked by the + * device, the device will not steer new packets on receive virtqueues + * other than specified nor read from transmit virtqueues other than + * specified. Accordingly, driver should not transmit new packets on + * virtqueues other than specified. + */ +struct virtio_net_ctrl_mq { + uint16_t virtqueue_pairs; +} _PACKED; + +#define VIRTIO_NET_CTRL_MQ 4 +#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0 +#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1 +#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000 + +#endif /* _VIRTIO_NET_H */ diff --git a/src/add-ons/kernel/file_systems/ext2/Inode.cpp b/src/add-ons/kernel/file_systems/ext2/Inode.cpp index 3a07a8c4c8..e8a1529ba0 100644 --- a/src/add-ons/kernel/file_systems/ext2/Inode.cpp +++ b/src/add-ons/kernel/file_systems/ext2/Inode.cpp @@ -633,8 +633,9 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, inode->SetAccessTime(×pec); inode->SetCreationTime(×pec); inode->SetModificationTime(×pec); - node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED); - if (volume->HasExtentsFeature() + if (parent != NULL) + node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED); + if (volume->HasExtentsFeature() && (inode->IsDirectory() || inode->IsFile())) { node.SetFlag(EXT2_INODE_EXTENTS); ExtentStream stream(volume, &node.extent_stream, 0); @@ -935,4 +936,3 @@ Inode::IncrementNumLinks(Transaction& transaction) fVolume->ActivateDirNLink(transaction); } } - diff --git a/src/add-ons/kernel/file_systems/ext2/ext2.h b/src/add-ons/kernel/file_systems/ext2/ext2.h index b966e7c72d..2bc5f7fc29 100644 --- a/src/add-ons/kernel/file_systems/ext2/ext2.h +++ b/src/add-ons/kernel/file_systems/ext2/ext2.h @@ -141,13 +141,13 @@ struct ext2_super_block { { free_blocks = B_HOST_TO_LENDIAN_INT32(freeBlocks & 0xffffffff); if (has64bits) - free_blocks_high = B_HOST_TO_LENDIAN_INT32(freeBlocks >> 32); + free_blocks_high = B_HOST_TO_LENDIAN_INT32(freeBlocks >> 32); } void SetLastOrphan(ino_t id) { last_orphan = B_HOST_TO_LENDIAN_INT32((uint32)id); } void SetReadOnlyFeatures(uint32 readOnlyFeatures) const { readOnlyFeatures = B_HOST_TO_LENDIAN_INT32(readOnlyFeatures); } - + bool IsValid(); // implemented in Volume.cpp } _PACKED; @@ -211,7 +211,7 @@ struct ext2_block_group { uint32 _reserved[2]; uint16 unused_inodes; uint16 checksum; - + // ext4 uint32 block_bitmap_high; uint32 inode_bitmap_high; @@ -249,7 +249,7 @@ struct ext2_block_group { { uint32 blocks = B_LENDIAN_TO_HOST_INT16(free_blocks); if (has64bits) - blocks |= + blocks |= ((uint32)B_LENDIAN_TO_HOST_INT16(free_blocks_high) << 16); return blocks; } @@ -257,7 +257,7 @@ struct ext2_block_group { { uint32 inodes = B_LENDIAN_TO_HOST_INT16(free_inodes); if (has64bits) - inodes |= + inodes |= ((uint32)B_LENDIAN_TO_HOST_INT16(free_inodes_high) << 16); return inodes; } @@ -265,7 +265,7 @@ struct ext2_block_group { { uint32 dirs = B_LENDIAN_TO_HOST_INT16(used_directories); if (has64bits) - dirs |= + dirs |= ((uint32)B_LENDIAN_TO_HOST_INT16(used_directories_high) << 16); return dirs; } @@ -274,11 +274,11 @@ struct ext2_block_group { { uint32 inodes = B_LENDIAN_TO_HOST_INT16(unused_inodes); if (has64bits) - inodes |= + inodes |= ((uint32)B_LENDIAN_TO_HOST_INT16(unused_inodes_high) << 16); return inodes; } - + void SetFreeBlocks(uint32 freeBlocks, bool has64bits) { @@ -376,7 +376,7 @@ struct ext2_extent_entry { uint32 physical_block; uint32 LogicalBlock() const { return B_LENDIAN_TO_HOST_INT32(logical_block); } - uint16 Length() const { return B_LENDIAN_TO_HOST_INT16(length) == 0x8000 + uint16 Length() const { return B_LENDIAN_TO_HOST_INT16(length) == 0x8000 ? 0x8000 : B_LENDIAN_TO_HOST_INT16(length) & 0x7fff; } uint64 PhysicalBlock() const { return B_LENDIAN_TO_HOST_INT32(physical_block) | ((uint64)B_LENDIAN_TO_HOST_INT16(physical_block_high) << 32); } @@ -437,7 +437,7 @@ struct ext2_inode { uint16 uid_high; uint16 gid_high; uint32 _reserved2; - + // extra attributes uint16 extra_inode_size; uint16 _padding2; @@ -460,18 +460,18 @@ struct ext2_inode { { timespec->tv_sec = B_LENDIAN_TO_HOST_INT32(time); if (extra && sizeof(timespec->tv_sec) > 4) - timespec->tv_sec |= + timespec->tv_sec |= (uint64)(B_LENDIAN_TO_HOST_INT32(time_extra) & 0x2) << 32; if (extra) timespec->tv_nsec = B_LENDIAN_TO_HOST_INT32(time_extra) >> 2; else timespec->tv_nsec = 0; } - - void GetModificationTime(struct timespec *timespec, bool extra) const - { _DecodeTime(timespec, modification_time, modification_time_extra, + + void GetModificationTime(struct timespec *timespec, bool extra) const + { _DecodeTime(timespec, modification_time, modification_time_extra, extra); } - void GetAccessTime(struct timespec *timespec, bool extra) const + void GetAccessTime(struct timespec *timespec, bool extra) const { _DecodeTime(timespec, access_time, access_time_extra, extra); } void GetChangeTime(struct timespec *timespec, bool extra) const { _DecodeTime(timespec, change_time, change_time_extra, extra); } @@ -494,7 +494,7 @@ struct ext2_inode { time |= (uint64)timespec->tv_sec >> 32; return B_HOST_TO_LENDIAN_INT32(time); } - + void SetModificationTime(const struct timespec *timespec, bool extra) { modification_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec); @@ -517,7 +517,7 @@ struct ext2_inode { { if (extra) { creation_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec); - creation_time_extra = + creation_time_extra = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_nsec); } } @@ -527,7 +527,7 @@ struct ext2_inode { } ino_t NextOrphan() const { return (ino_t)DeletionTime(); } - + off_t Size() const { if (S_ISREG(Mode())) { @@ -654,6 +654,10 @@ struct ext2_inode { #define EXT2_INODE_DIR_SYNCH 0x00010000 #define EXT2_INODE_HUGE_FILE 0x00040000 #define EXT2_INODE_EXTENTS 0x00080000 +#define EXT2_INODE_LARGE_EA 0x00200000 +#define EXT2_INODE_EOF_BLOCKS 0x00400000 +#define EXT2_INODE_INLINE_DATA 0x10000000 +#define EXT2_INODE_RESERVED 0x80000000 #define EXT2_INODE_INHERITED (EXT2_INODE_SECURE_DELETION | EXT2_INODE_UNDELETE \ | EXT2_INODE_COMPRESSED | EXT2_INODE_SYNCHRONOUS | EXT2_INODE_IMMUTABLE \ diff --git a/src/add-ons/kernel/file_systems/ntfs/fs_func.c b/src/add-ons/kernel/file_systems/ntfs/fs_func.c index b7ee6ead0d..430922da9c 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -274,7 +274,9 @@ fs_identify_partition(int fd, partition_data *partition, void **_cookie) *_cookie = cookie; - return 0.8f; + // Make sure we return a higher number than the intel partition check + // as this one is more accurate. + return 0.82f; } diff --git a/src/add-ons/kernel/generic/dpc/dpc.c b/src/add-ons/kernel/generic/dpc/dpc.c index 4b09253542..4557972c18 100644 --- a/src/add-ons/kernel/generic/dpc/dpc.c +++ b/src/add-ons/kernel/generic/dpc/dpc.c @@ -64,7 +64,7 @@ dpc_thread(void *arg) } // Let's finish the pending DPCs, if any. - // Otherwise, resource could leaks... + // Otherwise, resource could leak... while (queue->count--) { dpc = queue->slots[queue->head]; queue->head = (queue->head + 1) % queue->size; @@ -135,7 +135,7 @@ delete_dpc_queue(void *handle) if (!queue) return B_BAD_VALUE; - // Close the queue: queue_dpc() should knows we're closing: + // Close the queue: queue_dpc() should know we're closing: former = disable_interrupts(); acquire_spinlock(&queue->lock); @@ -186,8 +186,8 @@ queue_dpc(void *handle, dpc_func function, void *arg) restore_interrupts(former); if (status == B_OK) - // Wake up the corresponding dpc thead - // Notice that interrupt handlers should returns B_INVOKE_SCHEDULER to + // Wake up the corresponding dpc thread + // Notice that interrupt handlers should return B_INVOKE_SCHEDULER to // shorten DPC latency as much as possible... status = release_sem_etc(queue->wakeup_sem, 1, B_DO_NOT_RESCHEDULE); diff --git a/src/apps/debuganalyzer/gui/Jamfile b/src/apps/debuganalyzer/gui/Jamfile index a3b7e5bcab..fafe2552a8 100644 --- a/src/apps/debuganalyzer/gui/Jamfile +++ b/src/apps/debuganalyzer/gui/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui.o : AbstractGeneralPage.cpp diff --git a/src/apps/debuganalyzer/gui/chart/Jamfile b/src/apps/debuganalyzer/gui/chart/Jamfile index b24915372a..6a611cdc0e 100644 --- a/src/apps/debuganalyzer/gui/chart/Jamfile +++ b/src/apps/debuganalyzer/gui/chart/Jamfile @@ -4,9 +4,6 @@ UsePrivateHeaders shared ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui_chart.o : BigtimeChartAxisLegendSource.cpp diff --git a/src/apps/debuganalyzer/gui/main_window/Jamfile b/src/apps/debuganalyzer/gui/main_window/Jamfile index d045a19373..2479331aee 100644 --- a/src/apps/debuganalyzer/gui/main_window/Jamfile +++ b/src/apps/debuganalyzer/gui/main_window/Jamfile @@ -7,9 +7,6 @@ UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders [ FDirName $(HAIKU_TOP) src apps debugger util ] ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui_main_window.o : GeneralPage.cpp diff --git a/src/apps/debuganalyzer/gui/table/Jamfile b/src/apps/debuganalyzer/gui/table/Jamfile index f55bca6d11..da838b98b7 100644 --- a/src/apps/debuganalyzer/gui/table/Jamfile +++ b/src/apps/debuganalyzer/gui/table/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui_table.o : AbstractTable.cpp diff --git a/src/apps/debuganalyzer/gui/thread_window/Jamfile b/src/apps/debuganalyzer/gui/thread_window/Jamfile index 3e171d0251..5a96ee698f 100644 --- a/src/apps/debuganalyzer/gui/thread_window/Jamfile +++ b/src/apps/debuganalyzer/gui/thread_window/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui_thread_window.o : ActivityPage.cpp diff --git a/src/apps/debuganalyzer/model/Jamfile b/src/apps/debuganalyzer/model/Jamfile index 165c2f6d5a..22e4db74f2 100644 --- a/src/apps/debuganalyzer/model/Jamfile +++ b/src/apps/debuganalyzer/model/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_model.o : Model.cpp diff --git a/src/apps/debuganalyzer/model_loader/Jamfile b/src/apps/debuganalyzer/model_loader/Jamfile index ed9888b115..af860197e9 100644 --- a/src/apps/debuganalyzer/model_loader/Jamfile +++ b/src/apps/debuganalyzer/model_loader/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_model_loader.o : AbstractModelLoader.cpp diff --git a/src/apps/debuganalyzer/util/Jamfile b/src/apps/debuganalyzer/util/Jamfile index 8a5316a3f7..fd6ab0cbdf 100644 --- a/src/apps/debuganalyzer/util/Jamfile +++ b/src/apps/debuganalyzer/util/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_util.o : DataSource.cpp diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 56f1ed8577..1352fc5c36 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ; # for syscall_numbers.h @@ -184,6 +181,7 @@ Application Debugger : BreakpointSetting.cpp GuiTeamUiSettings.cpp SettingsManager.cpp + TeamFileManagerSettings.cpp TeamSettings.cpp TeamUiSettings.cpp TeamUiSettingsFactory.cpp diff --git a/src/apps/debugger/arch/x86/disasm/Jamfile b/src/apps/debugger/arch/x86/disasm/Jamfile index 0b40f9f7e0..284eac6400 100644 --- a/src/apps/debugger/arch/x86/disasm/Jamfile +++ b/src/apps/debugger/arch/x86/disasm/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger arch x86 disasm ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - UsePrivateHeaders shared ; UseHeaders [ LibraryHeaders udis86 ] ; diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp index 0922808fc1..73bd4a5651 100644 --- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp +++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp @@ -315,8 +315,8 @@ ArchitectureX8664::CreateStackFrame(Image* image, FunctionDebugInfo* function, // The syscall stubs are frameless, the return address is on top of the // stack. - uint32 rsp = cpuState->IntRegisterValue(X86_64_REGISTER_RSP); - uint32 address; + uint64 rsp = cpuState->IntRegisterValue(X86_64_REGISTER_RSP); + uint64 address; if (fTeamMemory->ReadMemory(rsp, &address, 8) == 8) { returnAddress = address; previousFramePointer = framePointer; diff --git a/src/apps/debugger/arch/x86_64/disasm/Jamfile b/src/apps/debugger/arch/x86_64/disasm/Jamfile index 7424d3d780..9b1289e0cf 100644 --- a/src/apps/debugger/arch/x86_64/disasm/Jamfile +++ b/src/apps/debugger/arch/x86_64/disasm/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger arch x86_64 disasm ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - UsePrivateHeaders shared ; UseHeaders [ LibraryHeaders udis86 ] ; diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index 66ac0f2966..60cdba9026 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -18,12 +18,15 @@ #include "AreaInfo.h" #include "CpuState.h" #include "DebuggerInterface.h" +#include "DisassembledCode.h" +#include "FunctionInstance.h" #include "Image.h" #include "MessageCodes.h" #include "Register.h" #include "SemaphoreInfo.h" #include "StackFrame.h" #include "StackTrace.h" +#include "Statement.h" #include "StringUtils.h" #include "SystemInfo.h" #include "Team.h" @@ -51,7 +54,8 @@ DebugReportGenerator::DebugReportGenerator(::Team* team, fWaitingNode(NULL), fCurrentBlock(NULL), fBlockRetrievalStatus(B_OK), - fTraceWaitingThread(NULL) + fTraceWaitingThread(NULL), + fSourceWaitingFunction(NULL) { fTeam->AddListener(this); fArchitecture->AcquireReference(); @@ -204,6 +208,20 @@ DebugReportGenerator::ValueNodeValueChanged(ValueNode* node) } +void +DebugReportGenerator::FunctionSourceCodeChanged(Function* function) +{ + AutoLocker< ::Team> teamLocker(fTeam); + if (function == fSourceWaitingFunction) { + if (function->FirstInstance()->SourceCodeState() + == FUNCTION_SOURCE_LOADED + || function->FirstInstance()->SourceCodeState() + == FUNCTION_SOURCE_UNAVAILABLE) { + release_sem(fTeamDataSem); + } + } +} + status_t DebugReportGenerator::_GenerateReportHeader(BString& _output) { @@ -452,9 +470,12 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, && frame->CountLocalVariables() == 0) { // only dump the topmost frame if (i == 0) { + locker.Unlock(); + _DumpFunctionDisassembly(_output, frame->InstructionPointer()); _DumpStackFrameMemory(_output, thread->GetCpuState(), frame->FrameAddress(), thread->GetTeam()->GetArchitecture() ->StackGrowthDirection()); + locker.Lock(); } continue; } @@ -495,6 +516,66 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, } +void +DebugReportGenerator::_DumpFunctionDisassembly(BString& _output, + target_addr_t instructionPointer) +{ + AutoLocker< ::Team> teamLocker(fTeam); + BString data; + FunctionInstance* instance = NULL; + Statement* statement = NULL; + status_t error = fTeam->GetStatementAtAddress(instructionPointer, instance, + statement); + if (error != B_OK) { + data.SetToFormat("Unable to retrieve disassembly for IP %#" B_PRIx64 + ": %s\n", instructionPointer, strerror(error)); + _output << data; + return; + } + + DisassembledCode* code = instance->GetSourceCode(); + Function* function = instance->GetFunction(); + if (code == NULL) { + switch (function->SourceCodeState()) { + case FUNCTION_SOURCE_NOT_LOADED: + function->AddListener(this); + fSourceWaitingFunction = function; + fListener->FunctionSourceCodeRequested(instance, true); + // fall through + case FUNCTION_SOURCE_LOADING: + { + teamLocker.Unlock(); + error = acquire_sem(fTeamDataSem); + if (error != B_OK) + return; + teamLocker.Lock(); + break; + } + default: + return; + } + + if (instance->SourceCodeState() == FUNCTION_SOURCE_UNAVAILABLE) + return; + + error = fTeam->GetStatementAtAddress(instructionPointer, instance, + statement); + code = instance->GetSourceCode(); + } + + SourceLocation location = statement->StartSourceLocation(); + + _output << "\t\t\tDisassembly:\n"; + for (int32 i = 0; i < location.Line(); i++) { + _output << "\t\t\t\t" << code->LineAt(i); + if (i == location.Line() - 1) + _output << " <--"; + _output << "\n"; + } + _output << "\n"; +} + + void DebugReportGenerator::_DumpStackFrameMemory(BString& _output, CpuState* state, target_addr_t framePointer, uint8 stackDirection) @@ -519,11 +600,11 @@ DebugReportGenerator::_DumpStackFrameMemory(BString& _output, _output << "\t\t\tFrame memory:\n"; if (fBlockRetrievalStatus == B_OK) { - UiUtils::DumpMemory(_output, 3, fCurrentBlock, startAddress, 1, 16, + UiUtils::DumpMemory(_output, 4 , fCurrentBlock, startAddress, 1, 16, endAddress - startAddress); } else { BString data; - data.SetToFormat("\t\t\tUnavailable (%s)\n", strerror( + data.SetToFormat("\t\t\t\tUnavailable (%s)\n", strerror( fBlockRetrievalStatus)); _output += data; } diff --git a/src/apps/debugger/controllers/DebugReportGenerator.h b/src/apps/debugger/controllers/DebugReportGenerator.h index 13746e9502..121bb5a20c 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.h +++ b/src/apps/debugger/controllers/DebugReportGenerator.h @@ -8,6 +8,7 @@ #include +#include "Function.h" #include "Team.h" #include "TeamMemoryBlock.h" #include "ValueNodeContainer.h" @@ -30,7 +31,8 @@ class ValueNodeManager; class DebugReportGenerator : public BLooper, private Team::Listener, - private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener { + private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener, + private Function::Listener { public: DebugReportGenerator(::Team* team, UserInterfaceListener* listener, @@ -58,6 +60,8 @@ private: // ValueNodeContainer::Listener virtual void ValueNodeValueChanged(ValueNode* node); + // Function::Listener + virtual void FunctionSourceCodeChanged(Function* function); private: status_t _GenerateReport(const entry_ref& outputPath); @@ -68,6 +72,8 @@ private: status_t _DumpRunningThreads(BString& _output); status_t _DumpDebuggedThreadInfo(BString& _output, ::Thread* thread); + void _DumpFunctionDisassembly(BString& _output, + target_addr_t instructionPointer); void _DumpStackFrameMemory(BString& _output, CpuState* state, target_addr_t framePointer, @@ -97,6 +103,7 @@ private: TeamMemoryBlock* fCurrentBlock; status_t fBlockRetrievalStatus; ::Thread* fTraceWaitingThread; + Function* fSourceWaitingFunction; }; #endif // DEBUG_REPORT_GENERATOR_H diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index b4a391b194..3226afa4b8 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -1991,6 +1991,8 @@ TeamDebugger::_LoadSettings() breakpointSetting->IsEnabled()); } + fFileManager->LoadLocationMappings(fTeamSettings.FileManagerSettings()); + const TeamUiSettings* uiSettings = fTeamSettings.UiSettingFor( fUserInterface->ID()); if (uiSettings != NULL) @@ -2022,6 +2024,8 @@ TeamDebugger::_SaveSettings() settings.AddUiSettings(clonedSettings); } } + + fFileManager->SaveLocationMappings(settings.FileManagerSettings()); locker.Unlock(); // save the settings diff --git a/src/apps/debugger/demangler/Jamfile b/src/apps/debugger/demangler/Jamfile index 613c6aace5..d71c877cf9 100644 --- a/src/apps/debugger/demangler/Jamfile +++ b/src/apps/debugger/demangler/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger demangler ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons kernel debugger demangle ] ; diff --git a/src/apps/debugger/dwarf/Jamfile b/src/apps/debugger/dwarf/Jamfile index 0efb29c52e..4cf6b78281 100644 --- a/src/apps/debugger/dwarf/Jamfile +++ b/src/apps/debugger/dwarf/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger dwarf ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - UsePrivateHeaders kernel shared ; UsePrivateSystemHeaders ; diff --git a/src/apps/debugger/files/FileManager.cpp b/src/apps/debugger/files/FileManager.cpp index aaa78f27a2..66fbe6391b 100644 --- a/src/apps/debugger/files/FileManager.cpp +++ b/src/apps/debugger/files/FileManager.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. */ @@ -15,6 +15,7 @@ #include "LocatableFile.h" #include "SourceFile.h" #include "StringUtils.h" +#include "TeamFileManagerSettings.h" // #pragma mark - EntryPath @@ -611,7 +612,8 @@ FileManager::GetTargetFile(const BString& path) void -FileManager::TargetEntryLocated(const BString& path, const BString& locatedPath) +FileManager::TargetEntryLocated(const BString& path, + const BString& locatedPath) { AutoLocker locker(this); fTargetDomain->EntryLocated(path, locatedPath); @@ -623,7 +625,14 @@ FileManager::GetSourceFile(const BString& directory, const BString& relativePath) { AutoLocker locker(this); - return fSourceDomain->GetFile(directory, relativePath); + LocatableFile* file = fSourceDomain->GetFile(directory, relativePath); + + if (directory.Length() == 0 || relativePath[0] == '/') + _LocateFileIfMapped(relativePath, file); + else + _LocateFileIfMapped(BString(directory) << '/' << relativePath, file); + + return file; } @@ -631,15 +640,27 @@ LocatableFile* FileManager::GetSourceFile(const BString& path) { AutoLocker locker(this); - return fSourceDomain->GetFile(path); + LocatableFile* file = fSourceDomain->GetFile(path); + _LocateFileIfMapped(path, file); + + return file; } -void -FileManager::SourceEntryLocated(const BString& path, const BString& locatedPath) +status_t +FileManager::SourceEntryLocated(const BString& path, + const BString& locatedPath) { AutoLocker locker(this); fSourceDomain->EntryLocated(path, locatedPath); + + try { + fSourceLocationMappings[path] = locatedPath; + } catch (...) { + return B_NO_MEMORY; + } + + return B_OK; } @@ -687,6 +708,45 @@ FileManager::LoadSourceFile(LocatableFile* file, SourceFile*& _sourceFile) } +status_t +FileManager::LoadLocationMappings(TeamFileManagerSettings* settings) +{ + AutoLocker locker(this); + + for (int32 i = 0; i < settings->CountSourceMappings(); i++) { + BString sourcePath; + BString locatedPath; + + if (settings->GetSourceMappingAt(i, sourcePath, locatedPath) != B_OK) + return B_NO_MEMORY; + + try { + fSourceLocationMappings[sourcePath] = locatedPath; + } catch (...) { + return B_NO_MEMORY; + } + } + + return B_OK; +} + + +status_t +FileManager::SaveLocationMappings(TeamFileManagerSettings* settings) +{ + AutoLocker locker(this); + + for (LocatedFileMap::const_iterator it = fSourceLocationMappings.begin(); + it != fSourceLocationMappings.end(); ++it) { + status_t error = settings->AddSourceMapping(it->first, it->second); + if (error != B_OK) + return error; + } + + return B_OK; +} + + FileManager::SourceFileEntry* FileManager::_LookupSourceFile(const BString& path) { @@ -713,3 +773,17 @@ FileManager::_SourceFileUnused(SourceFileEntry* entry) if (otherEntry == entry) fSourceFiles->Remove(entry); } + + +void +FileManager::_LocateFileIfMapped(const BString& sourcePath, + LocatableFile* file) +{ + // called with lock held + LocatedFileMap::const_iterator it = fSourceLocationMappings.find( + sourcePath); + if (it != fSourceLocationMappings.end() + && file->State() != LOCATABLE_ENTRY_LOCATED_EXPLICITLY) { + fSourceDomain->EntryLocated(it->first, it->second); + } +} diff --git a/src/apps/debugger/files/FileManager.h b/src/apps/debugger/files/FileManager.h index 559942152b..e008fa5b4b 100644 --- a/src/apps/debugger/files/FileManager.h +++ b/src/apps/debugger/files/FileManager.h @@ -1,11 +1,15 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef FILE_MANAGER_H #define FILE_MANAGER_H +#include + #include +#include #include #include @@ -15,6 +19,7 @@ class LocatableEntry; class LocatableFile; class SourceFile; +class TeamFileManagerSettings; class FileManager { @@ -40,13 +45,18 @@ public: // returns a reference LocatableFile* GetSourceFile(const BString& path); // returns a reference - void SourceEntryLocated(const BString& path, + status_t SourceEntryLocated(const BString& path, const BString& locatedPath); status_t LoadSourceFile(LocatableFile* file, SourceFile*& _sourceFile); // returns a reference + status_t LoadLocationMappings(TeamFileManagerSettings* + settings); + status_t SaveLocationMappings(TeamFileManagerSettings* + settings); + private: struct EntryPath; struct EntryHashDefinition; @@ -57,6 +67,7 @@ private: typedef BOpenHashTable LocatableEntryTable; typedef DoublyLinkedList DeadEntryList; typedef BOpenHashTable SourceFileTable; + typedef std::map LocatedFileMap; friend struct SourceFileEntry; // for gcc 2 @@ -64,12 +75,16 @@ private: private: SourceFileEntry* _LookupSourceFile(const BString& path); void _SourceFileUnused(SourceFileEntry* entry); + void _LocateFileIfMapped(const BString& sourcePath, + LocatableFile* file); private: BLocker fLock; Domain* fTargetDomain; Domain* fSourceDomain; SourceFileTable* fSourceFiles; + + LocatedFileMap fSourceLocationMappings; }; diff --git a/src/apps/debugger/settings/TeamFileManagerSettings.cpp b/src/apps/debugger/settings/TeamFileManagerSettings.cpp new file mode 100644 index 0000000000..dae7c79f0f --- /dev/null +++ b/src/apps/debugger/settings/TeamFileManagerSettings.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "TeamFileManagerSettings.h" + +TeamFileManagerSettings::TeamFileManagerSettings() + : + fValues() +{ +} + + +TeamFileManagerSettings::~TeamFileManagerSettings() +{ +} + + +TeamFileManagerSettings& +TeamFileManagerSettings::operator=(const TeamFileManagerSettings& other) +{ + fValues = other.fValues; + + return *this; +} + + +const char* +TeamFileManagerSettings::ID() const +{ + return "FileManager"; +} + + +status_t +TeamFileManagerSettings::SetTo(const BMessage& archive) +{ + try { + fValues = archive; + } catch (...) { + return B_NO_MEMORY; + } + + return B_OK; +} + + +status_t +TeamFileManagerSettings::WriteTo(BMessage& archive) const +{ + try { + archive = fValues; + } catch (...) { + return B_NO_MEMORY; + } + + return B_OK; +} + + +int32 +TeamFileManagerSettings::CountSourceMappings() const +{ + type_code type; + int32 count = 0; + + if (fValues.GetInfo("source:mapping", &type, &count) == B_OK) + return count; + + return 0; +} + + +status_t +TeamFileManagerSettings::AddSourceMapping(const BString& sourcePath, + const BString& locatedPath) +{ + BMessage mapping; + if (mapping.AddString("source:path", sourcePath) != B_OK + || mapping.AddString("source:locatedpath", locatedPath) != B_OK + || fValues.AddMessage("source:mapping", &mapping) != B_OK) { + return B_NO_MEMORY; + } + + return B_OK; +} + + +status_t +TeamFileManagerSettings::RemoveSourceMappingAt(int32 index) +{ + return fValues.RemoveData("source:mapping", index); +} + + +status_t +TeamFileManagerSettings::GetSourceMappingAt(int32 index, BString& sourcePath, + BString& locatedPath) +{ + BMessage mapping; + status_t error = fValues.FindMessage("source:mapping", index, &mapping); + if (error != B_OK) + return error; + + error = mapping.FindString("source:path", &sourcePath); + if (error != B_OK) + return error; + + return mapping.FindString("source:locatedpath", &locatedPath); +} + + +TeamFileManagerSettings* +TeamFileManagerSettings::Clone() const +{ + TeamFileManagerSettings* settings = new(std::nothrow) + TeamFileManagerSettings(); + + if (settings == NULL) + return NULL; + + if (settings->SetTo(fValues) != B_OK) { + delete settings; + return NULL; + } + + return settings; +} diff --git a/src/apps/debugger/settings/TeamFileManagerSettings.h b/src/apps/debugger/settings/TeamFileManagerSettings.h new file mode 100644 index 0000000000..5663ce3000 --- /dev/null +++ b/src/apps/debugger/settings/TeamFileManagerSettings.h @@ -0,0 +1,41 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef TEAM_FILE_MANAGER_SETTINGS_H +#define TEAM_FILE_MANAGER_SETTINGS_H + +#include + + +class TeamFileManagerSettings { +public: + TeamFileManagerSettings(); + virtual ~TeamFileManagerSettings(); + + TeamFileManagerSettings& + operator=( + const TeamFileManagerSettings& other); + // throws std::bad_alloc; + + const char* ID() const; + status_t SetTo(const BMessage& archive); + status_t WriteTo(BMessage& archive) const; + + int32 CountSourceMappings() const; + status_t AddSourceMapping(const BString& sourcePath, + const BString& locatedPath); + status_t RemoveSourceMappingAt(int32 index); + status_t GetSourceMappingAt(int32 index, + BString& sourcePath, BString& locatedPath); + + virtual TeamFileManagerSettings* + Clone() const; + // throws std::bad_alloc + +private: + BMessage fValues; +}; + + +#endif // TEAM_FILE_MANAGER_SETTINGS_H diff --git a/src/apps/debugger/settings/TeamSettings.cpp b/src/apps/debugger/settings/TeamSettings.cpp index cf3154151c..99c38a0be8 100644 --- a/src/apps/debugger/settings/TeamSettings.cpp +++ b/src/apps/debugger/settings/TeamSettings.cpp @@ -16,6 +16,7 @@ #include "ArchivingUtils.h" #include "BreakpointSetting.h" #include "Team.h" +#include "TeamFileManagerSettings.h" #include "TeamUiSettings.h" #include "TeamUiSettingsFactory.h" #include "UserBreakpoint.h" @@ -23,6 +24,7 @@ TeamSettings::TeamSettings() { + fFileManagerSettings = new TeamFileManagerSettings(); } @@ -115,6 +117,12 @@ TeamSettings::SetTo(const BMessage& archive) } } + if (archive.FindMessage("filemanagersettings", &childArchive) == B_OK) { + error = fFileManagerSettings->SetTo(childArchive); + if (error != B_OK) + return error; + } + return B_OK; } @@ -149,6 +157,14 @@ TeamSettings::WriteTo(BMessage& archive) const return error; } + error = fFileManagerSettings->WriteTo(childArchive); + if (error != B_OK) + return error; + + error = archive.AddMessage("filemanagersettings", &childArchive); + if (error != B_OK) + return error; + return B_OK; } @@ -234,10 +250,32 @@ TeamSettings::operator=(const TeamSettings& other) } } + *fFileManagerSettings = *other.fFileManagerSettings; + return *this; } +TeamFileManagerSettings* +TeamSettings::FileManagerSettings() const +{ + return fFileManagerSettings; +} + + +status_t +TeamSettings::SetFileManagerSettings(TeamFileManagerSettings* settings) +{ + try { + *fFileManagerSettings = *settings; + } catch (...) { + return B_NO_MEMORY; + } + + return B_OK; +} + + void TeamSettings::_Unset() { diff --git a/src/apps/debugger/settings/TeamSettings.h b/src/apps/debugger/settings/TeamSettings.h index f41f2bf8bd..6f71cda7ef 100644 --- a/src/apps/debugger/settings/TeamSettings.h +++ b/src/apps/debugger/settings/TeamSettings.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_SETTINGS_H @@ -15,6 +16,7 @@ class BMessage; class Team; class BreakpointSetting; class TeamUiSettings; +class TeamFileManagerSettings; class TeamSettings { @@ -41,6 +43,11 @@ public: TeamSettings& operator=(const TeamSettings& other); // throws std::bad_alloc + TeamFileManagerSettings* + FileManagerSettings() const; + status_t SetFileManagerSettings( + TeamFileManagerSettings* settings); + private: typedef BObjectList BreakpointList; typedef BObjectList UiSettingsList; @@ -51,6 +58,8 @@ private: private: BreakpointList fBreakpoints; UiSettingsList fUiSettings; + TeamFileManagerSettings* + fFileManagerSettings; BString fTeamName; }; diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index a59e96760e..8aaec0a1ff 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -11,20 +11,30 @@ #include #include +#include #include +#include +#include #include +#include +#include #include #include #include "Architecture.h" +#include "AutoDeleter.h" +#include "MessageCodes.h" #include "Team.h" #include "TeamMemoryBlock.h" enum { - MSG_TARGET_ADDRESS_CHANGED = 'mtac' + MSG_TARGET_ADDRESS_CHANGED = 'mtac', + MSG_VIEW_AUTOSCROLL = 'mvas' }; +static const bigtime_t kScrollTimer = 10000LL; + MemoryView::MemoryView(::Team* team, Listener* listener) : @@ -39,6 +49,10 @@ MemoryView::MemoryView(::Team* team, Listener* listener) fHexBlocksPerLine(0), fHexMode(HexMode8BitInt), fTextMode(TextModeASCII), + fSelectionBase(0), + fSelectionStart(0), + fSelectionEnd(0), + fScrollRunner(NULL), fListener(listener) { Architecture* architecture = team->GetArchitecture(); @@ -76,11 +90,14 @@ void MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address) { fTargetAddress = address; - if (fTargetBlock != NULL) + if (block != fTargetBlock && fTargetBlock != NULL) fTargetBlock->ReleaseReference(); - fTargetBlock = block; - fTargetBlock->AcquireReference(); + if (block != fTargetBlock) { + fTargetBlock = block; + fTargetBlock->AcquireReference(); + } + MakeFocus(true); BMessenger(this).SendMessage(MSG_TARGET_ADDRESS_CHANGED); } @@ -119,7 +136,7 @@ MemoryView::Draw(BRect rect) if (fTargetBlock == NULL) return; - uint32 hexBlockSize = (1 << fHexMode) + 1; + uint32 hexBlockSize = _GetHexDigitsPerBlock() + 1; uint32 blockByteSize = hexBlockSize / 2; if (fHexMode != HexModeNone && fTextMode != TextModeNone) { divider += (fHexBlocksPerLine * hexBlockSize + 1) * fCharWidth; @@ -156,7 +173,6 @@ MemoryView::Draw(BRect rect) DrawString(buffer, drawPoint); drawPoint.x += fCharWidth * (fTargetAddressSize + 2); PopState(); - if (fHexMode != HexModeNone) { if (currentAddress + (currentBlocksPerLine * blockByteSize) > maxAddress) { @@ -168,20 +184,15 @@ MemoryView::Draw(BRect rect) for (int32 j = 0; j < currentBlocksPerLine; j++) { const char* blockAddress = currentAddress + (j * blockByteSize); - _GetNextHexBlock(buffer, - std::min((size_t)hexBlockSize, sizeof(buffer)), - blockAddress); - DrawString(buffer, drawPoint); + _GetNextHexBlock(buffer, sizeof(buffer), blockAddress); if (targetAddress >= blockAddress && targetAddress < - blockAddress + blockByteSize) { + blockAddress + blockByteSize) { PushState(); - SetHighColor(B_TRANSPARENT_COLOR); - SetDrawingMode(B_OP_INVERT); - FillRect(BRect(drawPoint.x, drawPoint.y - fh.ascent, - drawPoint.x + (hexBlockSize - 1) * fCharWidth, - drawPoint.y + fh.descent)); + SetHighColor(make_color(216,0,0)); + DrawString(buffer, drawPoint); PopState(); - } + } else + DrawString(buffer, drawPoint); drawPoint.x += fCharWidth * hexBlockSize; } @@ -190,6 +201,7 @@ MemoryView::Draw(BRect rect) drawPoint.x += fCharWidth * hexBlockSize * (fHexBlocksPerLine - currentBlocksPerLine); } + if (fTextMode != TextModeNone) { drawPoint.x += fCharWidth; for (int32 j = 0; j < currentCharsPerLine; j++) { @@ -226,6 +238,15 @@ MemoryView::Draw(BRect rect) lineAddress += fTextCharsPerLine; } } + + if (fSelectionStart != fSelectionEnd) { + PushState(); + BRegion selectionRegion; + _GetSelectionRegion(selectionRegion); + SetDrawingMode(B_OP_INVERT); + FillRegion(&selectionRegion, B_SOLID_HIGH); + PopState(); + } } @@ -332,6 +353,11 @@ void MemoryView::MessageReceived(BMessage* message) { switch(message->what) { + case B_COPY: + { + _CopySelectionToClipboard(); + break; + } case MSG_TARGET_ADDRESS_CHANGED: { _RecalcScrollBars(); @@ -370,6 +396,11 @@ MemoryView::MessageReceived(BMessage* message) } break; } + case MSG_VIEW_AUTOSCROLL: + { + _HandleAutoScroll(); + break; + } default: { BView::MessageReceived(message); @@ -385,7 +416,78 @@ MemoryView::MouseDown(BPoint point) if (!IsFocus()) MakeFocus(true); - BView::MouseDown(point); + if (fTargetBlock == NULL) + return; + + int32 buttons; + if (Looper()->CurrentMessage()->FindInt32("buttons", &buttons) != B_OK) + buttons = B_PRIMARY_MOUSE_BUTTON; + + if (buttons == B_SECONDARY_MOUSE_BUTTON) { + _HandleContextMenu(point); + return; + } + + int32 offset = _GetOffsetAt(point); + if (offset < fSelectionStart || offset > fSelectionEnd) { + BRegion oldSelectionRegion; + _GetSelectionRegion(oldSelectionRegion); + fSelectionBase = offset; + fSelectionStart = fSelectionBase; + fSelectionEnd = fSelectionBase; + Invalidate(oldSelectionRegion.Frame()); + } + + SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); + fTrackingMouse = true; +} + + +void +MemoryView::MouseMoved(BPoint point, uint32 transit, const BMessage* message) +{ + if (!fTrackingMouse) + return; + + BRegion oldSelectionRegion; + _GetSelectionRegion(oldSelectionRegion); + int32 offset = _GetOffsetAt(point); + if (offset < fSelectionBase) { + fSelectionStart = offset; + fSelectionEnd = fSelectionBase; + } else { + fSelectionStart = fSelectionBase; + fSelectionEnd = offset; + } + + BRegion region; + _GetSelectionRegion(region); + region.Include(&oldSelectionRegion); + Invalidate(region.Frame()); + + switch (transit) { + case B_EXITED_VIEW: + fScrollRunner = new BMessageRunner(BMessenger(this), + new BMessage(MSG_VIEW_AUTOSCROLL), kScrollTimer); + break; + + case B_ENTERED_VIEW: + delete fScrollRunner; + fScrollRunner = NULL; + break; + + default: + break; + } +} + + +void +MemoryView::MouseUp(BPoint point) +{ + fTrackingMouse = false; + delete fScrollRunner; + fScrollRunner = NULL; } @@ -395,10 +497,12 @@ MemoryView::ScrollToSelection() if (fTargetBlock != NULL) { target_addr_t offset = fTargetAddress - fTargetBlock->BaseAddress(); int32 lineNumber = 0; - if (fHexBlocksPerLine > 0) - lineNumber = offset / (fHexBlocksPerLine * (1 << (fHexMode - 1))); - else if (fTextCharsPerLine > 0) + if (fHexBlocksPerLine > 0) { + lineNumber = offset / (fHexBlocksPerLine + * (_GetHexDigitsPerBlock() / 2)); + } else if (fTextCharsPerLine > 0) lineNumber = offset / fTextCharsPerLine; + float y = lineNumber * fLineHeight; if (y < Bounds().top) ScrollTo(0.0, y); @@ -429,40 +533,23 @@ MemoryView::_RecalcScrollBars() float max = 0.0; BScrollBar *scrollBar = ScrollBar(B_VERTICAL); if (fTargetBlock != NULL) { - BRect bounds = Bounds(); - // the left portion of the view is off limits since it - // houses the address offset of the current line - float baseWidth = bounds.Width() - ((fTargetAddressSize + 2) - * fCharWidth); - float hexWidth = 0.0; - float textWidth = 0.0; - int32 hexDigits = 1 << fHexMode; + int32 hexDigits = _GetHexDigitsPerBlock(); int32 sizeFactor = 1 + hexDigits; - if (fHexMode != HexModeNone) { - if (fTextMode != TextModeNone) { - float hexProportion = sizeFactor / (float)(sizeFactor - + hexDigits / 2); - hexWidth = baseWidth * hexProportion; - // when sharing the display between hex and text, - // we allocate a 2 character space to separate the views - hexWidth -= 2 * fCharWidth; - textWidth = baseWidth - hexWidth; - } else - hexWidth = baseWidth; - } else if (fTextMode != TextModeNone) - textWidth = baseWidth; + _RecalcBounds(); + float hexWidth = fHexRight - fHexLeft; int32 nybblesPerLine = int32(hexWidth / fCharWidth); fHexBlocksPerLine = 0; fTextCharsPerLine = 0; if (fHexMode != HexModeNone) { fHexBlocksPerLine = nybblesPerLine / sizeFactor; fHexBlocksPerLine &= ~1; + fHexRight = fHexLeft + (fHexBlocksPerLine * sizeFactor + * fCharWidth); if (fTextMode != TextModeNone) fTextCharsPerLine = fHexBlocksPerLine * hexDigits / 2; } else if (fTextMode != TextModeNone) - fTextCharsPerLine = int32(textWidth / fCharWidth); - + fTextCharsPerLine = int32((fTextRight - fTextLeft) / fCharWidth); int32 lineCount = 0; float totalHeight = 0.0; if (fHexBlocksPerLine > 0) { @@ -473,6 +560,7 @@ MemoryView::_RecalcScrollBars() totalHeight = lineCount * fLineHeight; if (totalHeight > 0.0) { + BRect bounds = Bounds(); max = totalHeight - bounds.Height(); scrollBar->SetProportion(bounds.Height() / totalHeight); scrollBar->SetSteps(fLineHeight, bounds.Height()); @@ -488,7 +576,8 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize, switch(fHexMode) { case HexMode8BitInt: { - snprintf(buffer, bufferSize, "%02" B_PRIx8, *address); + snprintf(buffer, bufferSize, "%02" B_PRIx8, + *((const uint8*)address)); break; } case HexMode16BitInt: @@ -558,6 +647,290 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize, } +int32 +MemoryView::_GetOffsetAt(BPoint point) const +{ + if (fTargetBlock == NULL) + return -1; + + // TODO: support selection in the text region as well + if (fHexMode == HexModeNone) + return -1; + + int32 lineNumber = int32(point.y / fLineHeight); + int32 charsPerBlock = _GetHexDigitsPerBlock() / 2; + int32 totalHexBlocks = fTargetBlock->Size() / charsPerBlock; + int32 lineCount = totalHexBlocks / fHexBlocksPerLine; + + if (lineNumber >= lineCount) + return -1; + + point.x -= fHexLeft; + if (point.x < 0) + point.x = 0; + else if (point.x > fHexRight) + point.x = fHexRight; + + float blockWidth = (charsPerBlock * 2 + 1) * fCharWidth; + int32 containingBlock = int32(floor(point.x / blockWidth)); + + return fHexBlocksPerLine * charsPerBlock * lineNumber + + containingBlock * charsPerBlock; +} + + +BPoint +MemoryView::_GetPointForOffset(int32 offset) const +{ + BPoint point; + int32 bytesPerLine = fHexBlocksPerLine * _GetHexDigitsPerBlock() / 2; + int32 line = offset / bytesPerLine; + int32 lineOffset = offset % bytesPerLine; + + point.x = fHexLeft + (lineOffset * 2 * fCharWidth) + + (lineOffset * 2 * fCharWidth / _GetHexDigitsPerBlock()); + point.y = line * fLineHeight; + + return point; +} + + +void +MemoryView::_RecalcBounds() +{ + fHexLeft = 0; + fHexRight = 0; + fTextLeft = 0; + fTextRight = 0; + + // the left bound is determined by the space taken up by the actual + // displayed addresses. + float left = _GetAddressDisplayWidth(); + float width = Bounds().Width() - left; + + if (fHexMode != HexModeNone) { + int32 hexDigits = _GetHexDigitsPerBlock(); + int32 sizeFactor = 1 + hexDigits; + if (fTextMode != TextModeNone) { + float hexProportion = sizeFactor / (float)(sizeFactor + + hexDigits / 2); + float hexWidth = width * hexProportion; + fTextLeft = left + hexWidth; + fHexLeft = left; + // when sharing the display between hex and text, + // we allocate a 2 character space to separate the views + hexWidth -= 2 * fCharWidth; + fHexRight = left + hexWidth; + } else { + fHexLeft = left; + fHexRight = left + width; + } + } else if (fTextMode != TextModeNone) { + fTextLeft = left; + fTextRight = left + width; + } +} + + +float +MemoryView::_GetAddressDisplayWidth() const +{ + return (fTargetAddressSize + 2) * fCharWidth; +} + + +void +MemoryView::_GetSelectionRegion(BRegion& region) +{ + region.MakeEmpty(); + BPoint startPoint = _GetPointForOffset(fSelectionStart); + BPoint endPoint = _GetPointForOffset(fSelectionEnd); + + BRect rect; + if (startPoint.y == endPoint.y) { + // single line case + rect.left = startPoint.x; + rect.top = startPoint.y; + rect.right = endPoint.x; + rect.bottom = endPoint.y + fLineHeight; + region.Include(rect); + } else { + float currentLine = startPoint.y; + + // first line + rect.left = startPoint.x; + rect.top = startPoint.y; + rect.right = fHexRight; + rect.bottom = startPoint.y + fLineHeight; + region.Include(rect); + currentLine += fLineHeight; + + // middle region + if (currentLine < endPoint.y) { + rect.left = fHexLeft; + rect.top = currentLine; + rect.right = fHexRight; + rect.bottom = endPoint.y; + region.Include(rect); + } + + rect.left = fHexLeft; + rect.top = endPoint.y; + rect.right = endPoint.x; + rect.bottom = endPoint.y + fLineHeight; + region.Include(rect); + } +} + + +void +MemoryView::_GetSelectedText(BString& text) +{ + if (fSelectionStart == fSelectionEnd) + return; + + text.Truncate(0); + + char* data = (char *)fTargetBlock->Data() + fSelectionStart; + int16 blockSize = _GetHexDigitsPerBlock() / 2; + int32 count = (fSelectionEnd - fSelectionStart) + / blockSize; + + char buffer[32]; + for (int32 i = 0; i < count; i++) { + _GetNextHexBlock(buffer, sizeof(buffer), data); + data += blockSize; + text << buffer; + if (i < count - 1) + text << " "; + } +} + + +void +MemoryView::_CopySelectionToClipboard() +{ + BString text; + _GetSelectedText(text); + + if (text.Length() > 0) { + be_clipboard->Lock(); + be_clipboard->Data()->RemoveData("text/plain"); + be_clipboard->Data()->AddData ("text/plain", + B_MIME_TYPE, text.String(), text.Length()); + be_clipboard->Commit(); + be_clipboard->Unlock(); + } +} + + +void +MemoryView::_HandleAutoScroll() +{ + BPoint point; + uint32 buttons; + GetMouse(&point, &buttons); + float difference = 0.0; + int factor = 0; + BRect visibleRect = Bounds(); + if (point.y < visibleRect.top) + difference = point.y - visibleRect.top; + else if (point.y > visibleRect.bottom) + difference = point.y - visibleRect.bottom; + if (difference != 0.0) { + factor = (int)(ceilf(difference / fLineHeight)); + _ScrollByLines(factor); + } + + MouseMoved(point, B_OUTSIDE_VIEW, NULL); +} + + +void +MemoryView::_ScrollByLines(int32 lineCount) +{ + BScrollBar* vertical = ScrollBar(B_VERTICAL); + if (vertical == NULL) + return; + + float value = vertical->Value(); + vertical->SetValue(value + fLineHeight * lineCount); +} + + +void +MemoryView::_HandleContextMenu(BPoint point) +{ + int32 offset = _GetOffsetAt(point); + if (offset < fSelectionStart || offset > fSelectionEnd) + return; + + BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("Options"); + if (menu == NULL) + return; + + ObjectDeleter menuDeleter(menu); + ObjectDeleter itemDeleter; + ObjectDeleter messageDeleter; + BMessage* message = NULL; + BMenuItem* item = NULL; + if (fSelectionEnd - fSelectionStart == fTargetAddressSize / 2) { + BMessage* message = new(std::nothrow) BMessage(MSG_INSPECT_ADDRESS); + if (message == NULL) + return; + + target_addr_t address; + if (fTargetAddressSize == 8) + address = *((uint32*)(fTargetBlock->Data() + fSelectionStart)); + else + address = *((uint64*)(fTargetBlock->Data() + fSelectionStart)); + + if (fCurrentEndianMode == EndianModeBigEndian) + address = B_HOST_TO_BENDIAN_INT64(address); + else + address = B_HOST_TO_LENDIAN_INT64(address); + + messageDeleter.SetTo(message); + message->AddUInt64("address", address); + BMenuItem* item = new(std::nothrow) BMenuItem("Inspect", message); + if (item == NULL) + return; + + messageDeleter.Detach(); + itemDeleter.SetTo(item); + if (!menu->AddItem(item)) + return; + + item->SetTarget(Looper()); + itemDeleter.Detach(); + } + + message = new(std::nothrow) BMessage(B_COPY); + if (message == NULL) + return; + + messageDeleter.SetTo(message); + item = new(std::nothrow) BMenuItem("Copy", message); + if (item == NULL) + return; + + messageDeleter.Detach(); + itemDeleter.SetTo(item); + if (!menu->AddItem(item)) + return; + + item->SetTarget(this); + itemDeleter.Detach(); + menuDeleter.Detach(); + + BPoint screenWhere(point); + ConvertToScreen(&screenWhere); + BRect mouseRect(screenWhere, screenWhere); + mouseRect.InsetBy(-4.0, -4.0); + menu->Go(screenWhere, true, false, mouseRect, true); +} + + //#pragma mark - Listener diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h index ca10a25c48..9731971432 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h @@ -38,9 +38,9 @@ enum { }; +class BMessageRunner; + class Team; - - class TeamMemoryBlock; @@ -66,6 +66,9 @@ public: virtual void MakeFocus(bool isFocused); virtual void MessageReceived(BMessage* message); virtual void MouseDown(BPoint point); + virtual void MouseMoved(BPoint point, uint32 transit, + const BMessage* dragMessage); + virtual void MouseUp(BPoint point); void ScrollToSelection(); virtual void TargetedByScrollView(BScrollView* scrollView); @@ -75,6 +78,22 @@ private: void _GetNextHexBlock(char* buffer, int32 bufferSize, const char* address); + int32 _GetOffsetAt(BPoint point) const; + BPoint _GetPointForOffset(int32 offset) const; + void _RecalcBounds(); + float _GetAddressDisplayWidth() const; + + inline int32 _GetHexDigitsPerBlock() const + { return 1 << fHexMode; }; + + void _GetSelectionRegion(BRegion& region); + void _GetSelectedText(BString& text); + void _CopySelectionToClipboard(); + + void _HandleAutoScroll(); + void _ScrollByLines(int32 lineCount); + void _HandleContextMenu(BPoint point); + private: ::Team* fTeam; TeamMemoryBlock* fTargetBlock; @@ -87,6 +106,17 @@ private: int32 fCurrentEndianMode; int32 fHexMode; int32 fTextMode; + float fHexLeft; + float fHexRight; + float fTextLeft; + float fTextRight; + int32 fSelectionBase; + int32 fSelectionStart; + int32 fSelectionEnd; + BMessageRunner* fScrollRunner; + + bool fTrackingMouse; + Listener* fListener; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp b/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp index 239b6f5738..9dafae441d 100644 --- a/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -11,12 +11,17 @@ #include #include +#include +#include +#include #include "table/TableColumns.h" #include "Architecture.h" +#include "AutoDeleter.h" #include "CpuState.h" #include "GuiSettingsUtils.h" +#include "MessageCodes.h" #include "Register.h" #include "UiUtils.h" @@ -229,6 +234,48 @@ RegistersView::TableRowInvoked(Table* table, int32 rowIndex) } +void +RegistersView::TableCellMouseDown(Table* table, int32 rowIndex, + int32 columnIndex, BPoint screenWhere, uint32 buttons) +{ + if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0) + return; + + BVariant value; + if (!fRegisterTableModel->GetValueAt(rowIndex, 1, value)) + return; + + BPopUpMenu* menu = new(std::nothrow)BPopUpMenu("Options"); + if (menu == NULL) + return; + + ObjectDeleter menuDeleter(menu); + BMessage* message = new(std::nothrow)BMessage(MSG_SHOW_INSPECTOR_WINDOW); + if (message == NULL) + return; + + message->AddUInt64("address", value.ToUInt64()); + + ObjectDeleter messageDeleter(message); + BMenuItem* item = new(std::nothrow)BMenuItem("Inspect", message); + if (item == NULL) + return; + + messageDeleter.Detach(); + ObjectDeleter itemDeleter(item); + if (!menu->AddItem(item)) + return; + + itemDeleter.Detach(); + menu->SetTargetForItems(Window()); + menuDeleter.Detach(); + + BRect mouseRect(screenWhere, screenWhere); + mouseRect.InsetBy(-4.0, -4.0); + menu->Go(screenWhere, true, false, mouseRect, true); +} + + void RegistersView::_Init() { diff --git a/src/apps/debugger/user_interface/gui/team_window/RegistersView.h b/src/apps/debugger/user_interface/gui/team_window/RegistersView.h index 8c680928c8..e3c0b27e4f 100644 --- a/src/apps/debugger/user_interface/gui/team_window/RegistersView.h +++ b/src/apps/debugger/user_interface/gui/team_window/RegistersView.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef REGISTERS_VIEW_H @@ -35,6 +36,10 @@ private: // TableListener virtual void TableRowInvoked(Table* table, int32 rowIndex); + virtual void TableCellMouseDown(Table* table, int32 rowIndex, + int32 columnIndex, BPoint screenWhere, + uint32 buttons); + void _Init(); private: 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 113c6cb8f4..b3cd434ef0 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -2103,7 +2103,7 @@ status_t VariablesView::_AddContextAction(const char* action, uint32 what, ContextActionList* actions, BMessage*& _message) { - _message = new BMessage(what); + _message = new(std::nothrow) BMessage(what); if (_message == NULL) return B_NO_MEMORY; diff --git a/src/apps/haiku-depot/Jamfile b/src/apps/haiku-depot/Jamfile index 7788c34840..65196d0261 100644 --- a/src/apps/haiku-depot/Jamfile +++ b/src/apps/haiku-depot/Jamfile @@ -38,6 +38,7 @@ Application HaikuDepot : MainWindow.cpp Model.cpp PackageInfo.cpp + PackageInfoListener.cpp PackageInfoView.cpp PackageListView.cpp PackageManager.cpp diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index b7b0552c87..1f09cf575a 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -39,8 +40,8 @@ MainWindow::MainWindow(BRect frame) _BuildMenu(menuBar); fFilterView = new FilterView(fModel); - fPackageListView = new PackageListView(); - fPackageInfoView = new PackageInfoView(&fPackageManager); + fPackageListView = new PackageListView(fModel.Lock()); + fPackageInfoView = new PackageInfoView(fModel.Lock(), &fPackageManager); fSplitView = new BSplitView(B_VERTICAL, 5.0f); @@ -87,14 +88,22 @@ MainWindow::MessageReceived(BMessage* message) switch (message->what) { case B_SIMPLE_DATA: case B_REFS_RECEIVED: + // TODO: ? break; case MSG_PACKAGE_SELECTED: { - int32 index; - if (message->FindInt32("index", &index) == B_OK - && index >= 0 && index < fVisiblePackages.CountItems()) { - _AdoptPackage(fVisiblePackages.ItemAtFast(index)); + BString title; + if (message->FindString("title", &title) == B_OK) { + int count = fVisiblePackages.CountItems(); + for (int i = 0; i < count; i++) { + const PackageInfoRef& package + = fVisiblePackages.ItemAtFast(i); + if (package.Get() != NULL && package->Title() == title) { + _AdoptPackage(package); + break; + } + } } else { _ClearPackage(); } @@ -154,15 +163,17 @@ MainWindow::_AdoptModel() fPackageListView->Clear(); for (int32 i = 0; i < fVisiblePackages.CountItems(); i++) { + BAutolock _(fModel.Lock()); fPackageListView->AddPackage(fVisiblePackages.ItemAtFast(i)); } } void -MainWindow::_AdoptPackage(const PackageInfo& package) +MainWindow::_AdoptPackage(const PackageInfoRef& package) { fPackageInfoView->SetPackage(package); + fModel.PopulatePackage(package); } @@ -176,14 +187,17 @@ MainWindow::_ClearPackage() void MainWindow::_InitDummyModel() { - // TODO: The Model could be filled from another thread by - // sending messages which contain collected package information. - // The Model could be cached on disk. + // TODO: The Model needs to be filled initially by the Package Kit APIs. + // It already caches information locally. Error handlers need to be + // installed to display problems to the user. When a package is selected + // for display, extra information is retrieved like screen-shots, user- + // ratings and so on. This triggers notifications which in turn updates + // the UI. DepotInfo depot(B_TRANSLATE("Default")); // WonderBrush - PackageInfo wonderbrush( + PackageInfoRef wonderbrush(new(std::nothrow) PackageInfo( BitmapRef(new SharedBitmap(601), true), "WonderBrush", "2.1.2", @@ -196,24 +210,14 @@ MainWindow::_InitDummyModel() "WonderBrush is YellowBites' software for doing graphics design " "on Haiku. It combines many great under-the-hood features with " "powerful tools and an efficient and intuitive interface.", - "2.1.2 - Initial Haiku release."); - wonderbrush.AddUserRating( - UserRating(UserInfo("humdinger"), 4.5f, - "Awesome!", "en", "2.1.2", 0, 0) - ); - wonderbrush.AddUserRating( - UserRating(UserInfo("bonefish"), 5.0f, - "The best!", "en", "2.1.2", 3, 1) - ); - wonderbrush.AddScreenshot( - BitmapRef(new SharedBitmap(603), true)); - wonderbrush.AddCategory(fModel.CategoryGraphics()); - wonderbrush.AddCategory(fModel.CategoryProductivity()); + "2.1.2 - Initial Haiku release."), true); + wonderbrush->AddCategory(fModel.CategoryGraphics()); + wonderbrush->AddCategory(fModel.CategoryProductivity()); depot.AddPackage(wonderbrush); // Paladin - PackageInfo paladin( + PackageInfoRef paladin(new(std::nothrow) PackageInfo( BitmapRef(new SharedBitmap(602), true), "Paladin", "1.2.0", @@ -227,30 +231,13 @@ MainWindow::_InitDummyModel() "The interface is streamlined, it has some features sorely " "missing from BeIDE, like running a project in the Terminal, " "and has a bundled text editor based upon Pe.", - ""); - paladin.AddUserRating( - UserRating(UserInfo("stippi"), 3.5f, - "Could be more integrated from the sounds of it.", - "en", "1.2.0", 0, 1) - ); - paladin.AddUserRating( - UserRating(UserInfo("mmadia"), 5.0f, - "It rocks! Give a try", - "en", "1.1.0", 1, 0) - ); - paladin.AddUserRating( - UserRating(UserInfo("bonefish"), 2.0f, - "It just needs to use my jam-rewrite 'ham' and it will be great.", - "en", "1.1.0", 3, 1) - ); - paladin.AddScreenshot( - BitmapRef(new SharedBitmap(605), true)); - paladin.AddCategory(fModel.CategoryDevelopment()); + ""), true); + paladin->AddCategory(fModel.CategoryDevelopment()); depot.AddPackage(paladin); // Sequitur - PackageInfo sequitur( + PackageInfoRef sequitur(new(std::nothrow) PackageInfo( BitmapRef(new SharedBitmap(604), true), "Sequitur", "2.1.0", @@ -314,26 +301,8 @@ MainWindow::_InitDummyModel() "pressure events. The new tool Broken Down Line uses this " "filter.\n\n" " * ''Note to filter developers:'' The filter API has changed. You " - "will need to recompile your filters."); - sequitur.AddUserRating( - UserRating(UserInfo("pete"), 4.5f, - "I can weave a web of sound! And it connects to PatchBay. Check " - "it out, I can wholeheartly recommend this app!! This rating " - "comment is of course only so long, because the new TextView " - "layout needs some testing. Oh, and did I mention it works with " - "custom installed sound fonts? Reading through this comment I find " - "that I did not until now. Hopefully there are enough lines now to " - "please the programmer with the text layouting and scrolling of " - "long ratings!", "en", "2.1.0", 4, 1) - ); - sequitur.AddUserRating( - UserRating(UserInfo("stippi"), 3.5f, - "It seems very capable. Still runs fine on Haiku. The interface " - "is composed of many small, hard to click items. But you can " - "configure a tool for each mouse button, which is great for the " - "work flow.", "en", "2.1.0", 2, 1) - ); - sequitur.AddCategory(fModel.CategoryAudio()); + "will need to recompile your filters."), true); + sequitur->AddCategory(fModel.CategoryAudio()); depot.AddPackage(sequitur); diff --git a/src/apps/haiku-depot/MainWindow.h b/src/apps/haiku-depot/MainWindow.h index 694f32dc7b..b848741f9a 100644 --- a/src/apps/haiku-depot/MainWindow.h +++ b/src/apps/haiku-depot/MainWindow.h @@ -35,7 +35,7 @@ private: void _BuildMenu(BMenuBar* menuBar); void _AdoptModel(); - void _AdoptPackage(const PackageInfo& package); + void _AdoptPackage(const PackageInfoRef& package); void _ClearPackage(); void _InitDummyModel(); diff --git a/src/apps/haiku-depot/Model.cpp b/src/apps/haiku-depot/Model.cpp index 6557bd16b6..fecc10f5f4 100644 --- a/src/apps/haiku-depot/Model.cpp +++ b/src/apps/haiku-depot/Model.cpp @@ -7,6 +7,7 @@ #include +#include #include @@ -24,7 +25,7 @@ PackageFilter::~PackageFilter() class AnyFilter : public PackageFilter { public: - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { return true; } @@ -39,7 +40,7 @@ public: { } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { // TODO: Maybe a PackageInfo ought to know the Depot it came from? // But right now the same package could theoretically be provided @@ -68,9 +69,11 @@ public: { } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { - const CategoryList& categories = package.Categories(); + if (package.Get() == NULL) + return false; + const CategoryList& categories = package->Categories(); for (int i = categories.CountItems() - 1; i >= 0; i--) { const CategoryRef& category = categories.ItemAtFast(i); if (category.Get() == NULL) @@ -94,7 +97,7 @@ public: { } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { return fPackageList.Contains(package); } @@ -114,7 +117,7 @@ public: { } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { return fPackageListA.Contains(package) || fPackageListB.Contains(package); @@ -146,15 +149,17 @@ public: } } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { + if (package.Get() == NULL) + return false; // Every search term must be found in one of the package texts for (int32 i = fSearchTerms.CountItems() - 1; i >= 0; i--) { const BString& term = fSearchTerms.ItemAtFast(i); - if (!_TextContains(package.Title(), term) - && !_TextContains(package.Publisher().Name(), term) - && !_TextContains(package.ShortDescription(), term) - && !_TextContains(package.FullDescription(), term)) { + if (!_TextContains(package->Title(), term) + && !_TextContains(package->Publisher().Name(), term) + && !_TextContains(package->ShortDescription(), term) + && !_TextContains(package->FullDescription(), term)) { return false; } } @@ -263,7 +268,7 @@ Model::CreatePackageList() const const PackageList& packages = depot.Packages(); for (int32 j = 0; j < packages.CountItems(); j++) { - const PackageInfo& package = packages.ItemAtFast(j); + const PackageInfoRef& package = packages.ItemAtFast(j); if (fCategoryFilter->AcceptsPackage(package) && fSearchTermsFilter->AcceptsPackage(package)) { resultList.Add(package); @@ -283,7 +288,7 @@ Model::AddDepot(const DepotInfo& depot) void -Model::SetPackageState(const PackageInfo& package, PackageState state) +Model::SetPackageState(const PackageInfoRef& package, PackageState state) { switch (state) { default: @@ -362,3 +367,86 @@ Model::SetSearchTerms(const BString& searchTerms) fSearchTermsFilter.SetTo(filter, true); } + +// #pragma mark - information retrival + + +void +Model::PopulatePackage(const PackageInfoRef& package) +{ + if (fPopulatedPackages.Contains(package)) + return; + + BAutolock _(&fLock); + + // TODO: Replace with actual backend that retrieves package extra + // information and user-contributed package information. + + // TODO: There should probably also be a way to "unpopulate" the + // package information. Maybe a cache of populated packages, so that + // packages loose their extra information after a certain amount of + // time when they have not been accessed/displayed in the UI. Otherwise + // HaikuDepot will consume more and more resources in the packages. + // Especially screen-shots will be a problem eventually. + + // TODO: Simulate a delay in retrieving this info, and do that on + // a separate thread. + + fPopulatedPackages.Add(package); + + if (package->Title() == "WonderBrush") { + + package->AddUserRating( + UserRating(UserInfo("humdinger"), 4.5f, + "Awesome!", "en", "2.1.2", 0, 0) + ); + package->AddUserRating( + UserRating(UserInfo("bonefish"), 5.0f, + "The best!", "en", "2.1.2", 3, 1) + ); + package->AddScreenshot( + BitmapRef(new SharedBitmap(603), true)); + + } else if (package->Title() == "Paladin") { + + package->AddUserRating( + UserRating(UserInfo("stippi"), 3.5f, + "Could be more integrated from the sounds of it.", + "en", "1.2.0", 0, 1) + ); + package->AddUserRating( + UserRating(UserInfo("mmadia"), 5.0f, + "It rocks! Give a try", + "en", "1.1.0", 1, 0) + ); + package->AddUserRating( + UserRating(UserInfo("bonefish"), 2.0f, + "It just needs to use my jam-rewrite 'ham' and it will be great.", + "en", "1.1.0", 3, 1) + ); + package->AddScreenshot( + BitmapRef(new SharedBitmap(605), true)); + + } else if (package->Title() == "Sequitur") { + + package->AddUserRating( + UserRating(UserInfo("pete"), 4.5f, + "I can weave a web of sound! And it connects to PatchBay. Check " + "it out, I can wholeheartly recommend this app!! This rating " + "comment is of course only so long, because the new TextView " + "layout needs some testing. Oh, and did I mention it works with " + "custom installed sound fonts? Reading through this comment I find " + "that I did not until now. Hopefully there are enough lines now to " + "please the programmer with the text layouting and scrolling of " + "long ratings!", "en", "2.1.0", 4, 1) + ); + package->AddUserRating( + UserRating(UserInfo("stippi"), 3.5f, + "It seems very capable. Still runs fine on Haiku. The interface " + "is composed of many small, hard to click items. But you can " + "configure a tool for each mouse button, which is great for the " + "work flow.", "en", "2.1.0", 2, 1) + ); + + } +} diff --git a/src/apps/haiku-depot/Model.h b/src/apps/haiku-depot/Model.h index 87ff560d3e..f6f5087c20 100644 --- a/src/apps/haiku-depot/Model.h +++ b/src/apps/haiku-depot/Model.h @@ -5,6 +5,7 @@ #ifndef MODEL_H #define MODEL_H +#include #include "PackageInfo.h" @@ -14,7 +15,7 @@ public: virtual ~PackageFilter(); virtual bool AcceptsPackage( - const PackageInfo& package) const = 0; + const PackageInfoRef& package) const = 0; }; typedef BReference PackageFilterRef; @@ -24,6 +25,9 @@ class Model { public: Model(); + BLocker* Lock() + { return &fLock; } + // !Returns new PackageInfoList from current parameters PackageList CreatePackageList() const; @@ -55,7 +59,7 @@ public: { return fProgressCategories; } void SetPackageState( - const PackageInfo& package, + const PackageInfoRef& package, PackageState state); // Configure PackageFilters @@ -63,7 +67,12 @@ public: void SetDepot(const BString& depot); void SetSearchTerms(const BString& searchTerms); + // Retrieve package information + void PopulatePackage(const PackageInfoRef& package); + private: + BLocker fLock; + DepotList fDepots; CategoryRef fCategoryAudio; @@ -84,6 +93,7 @@ private: PackageList fUninstalledPackages; PackageList fDownloadingPackages; PackageList fUpdateablePackages; + PackageList fPopulatedPackages; PackageFilterRef fCategoryFilter; BString fDepotFilter; diff --git a/src/apps/haiku-depot/PackageInfo.cpp b/src/apps/haiku-depot/PackageInfo.cpp index 7172b80929..2823c77437 100644 --- a/src/apps/haiku-depot/PackageInfo.cpp +++ b/src/apps/haiku-depot/PackageInfo.cpp @@ -535,7 +535,12 @@ PackageInfo::AddCategory(const CategoryRef& category) bool PackageInfo::AddUserRating(const UserRating& rating) { - return fUserRatings.Add(rating); + if (!fUserRatings.Add(rating)) + return false; + + _NotifyListeners(PKG_CHANGED_RATINGS); + + return true; } @@ -584,7 +589,50 @@ PackageInfo::CalculateRatingSummary() const bool PackageInfo::AddScreenshot(const BitmapRef& screenshot) { - return fScreenshots.Add(screenshot); + if (!fScreenshots.Add(screenshot)) + return false; + + _NotifyListeners(PKG_CHANGED_SCREENSHOTS); + + return true; +} + + +bool +PackageInfo::AddListener(const PackageInfoListenerRef& listener) +{ + return fListeners.Add(listener); +} + + +void +PackageInfo::RemoveListener(const PackageInfoListenerRef& listener) +{ + fListeners.Remove(listener); +} + + +void +PackageInfo::_NotifyListeners(uint32 changes) +{ + int count = fListeners.CountItems(); + if (count == 0) + return; + + // Clone list to avoid listeners detaching themselves in notifications + // to screw up the list while iterating it. + PackageListenerList listeners(fListeners); + // Check if it worked: + if (listeners.CountItems () != count) + return; + + PackageInfoEvent event(PackageInfoRef(this), changes); + + for (int i = 0; i < count; i++) { + const PackageInfoListenerRef& listener = listeners.ItemAtFast(i); + if (listener.Get() != NULL) + listener->PackageChanged(event); + } } @@ -640,7 +688,7 @@ DepotInfo::operator!=(const DepotInfo& other) const bool -DepotInfo::AddPackage(const PackageInfo& package) +DepotInfo::AddPackage(const PackageInfoRef& package) { return fPackages.Add(package); } diff --git a/src/apps/haiku-depot/PackageInfo.h b/src/apps/haiku-depot/PackageInfo.h index c66aecd4ee..f4f74fa13f 100644 --- a/src/apps/haiku-depot/PackageInfo.h +++ b/src/apps/haiku-depot/PackageInfo.h @@ -10,6 +10,7 @@ #include #include "List.h" +#include "PackageInfoListener.h" class BBitmap; @@ -181,7 +182,10 @@ typedef BReference CategoryRef; typedef List CategoryList; -class PackageInfo { +typedef List PackageListenerList; + + +class PackageInfo : public BReferenceable { public: PackageInfo(); PackageInfo(const BitmapRef& icon, @@ -225,6 +229,14 @@ public: const BitmapList& Screenshots() const { return fScreenshots; } + bool AddListener( + const PackageInfoListenerRef& listener); + void RemoveListener( + const PackageInfoListenerRef& listener); + +private: + void _NotifyListeners(uint32 changes); + private: BitmapRef fIcon; BString fTitle; @@ -236,10 +248,14 @@ private: CategoryList fCategories; UserRatingList fUserRatings; BitmapList fScreenshots; + PackageListenerList fListeners; }; -typedef List PackageList; +typedef BReference PackageInfoRef; + + +typedef List PackageList; enum PackageState { @@ -266,7 +282,7 @@ public: const PackageList& Packages() const { return fPackages; } - bool AddPackage(const PackageInfo& package); + bool AddPackage(const PackageInfoRef& package); private: BString fName; diff --git a/src/apps/haiku-depot/PackageInfoListener.cpp b/src/apps/haiku-depot/PackageInfoListener.cpp new file mode 100644 index 0000000000..7329c2b365 --- /dev/null +++ b/src/apps/haiku-depot/PackageInfoListener.cpp @@ -0,0 +1,86 @@ +/* + * Copyright 2013, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "PackageInfoListener.h" + +#include + +#include "PackageInfo.h" + + +// #pragma mark - PackageInfoEvent + + +PackageInfoEvent::PackageInfoEvent() + : + fPackage(), + fChanges(0) +{ +} + + +PackageInfoEvent::PackageInfoEvent(const PackageInfoRef& package, + uint32 changes) + : + fPackage(package), + fChanges(changes) +{ +} + + +PackageInfoEvent::PackageInfoEvent(const PackageInfoEvent& other) + : + fPackage(other.fPackage), + fChanges(other.fChanges) +{ +} + + +PackageInfoEvent::~PackageInfoEvent() +{ +} + + +bool +PackageInfoEvent::operator==(const PackageInfoEvent& other) +{ + if (this == &other) + return true; + + return fPackage == other.fPackage + && fChanges == other.fChanges; +} + + +bool +PackageInfoEvent::operator!=(const PackageInfoEvent& other) +{ + return !(*this == other); +} + + +PackageInfoEvent& +PackageInfoEvent::operator=(const PackageInfoEvent& other) +{ + if (this != &other) { + fPackage = other.fPackage; + fChanges = other.fChanges; + } + + return *this; +} + + +// #pragma mark - PackageInfoListener + + +PackageInfoListener::PackageInfoListener() +{ +} + + +PackageInfoListener::~PackageInfoListener() +{ +} diff --git a/src/apps/haiku-depot/PackageInfoListener.h b/src/apps/haiku-depot/PackageInfoListener.h new file mode 100644 index 0000000000..323733ab3a --- /dev/null +++ b/src/apps/haiku-depot/PackageInfoListener.h @@ -0,0 +1,61 @@ +/* + * Copyright 2013, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef PACKAGE_INFO_LISTENER_H +#define PACKAGE_INFO_LISTENER_H + + +#include + + +enum { + PKG_CHANGED_DESCRIPTION = 1 << 0, + PKG_CHANGED_RATINGS = 1 << 1, + PKG_CHANGED_SCREENSHOTS = 1 << 2, + // ... +}; + + +class PackageInfo; +typedef BReference PackageInfoRef; + + +class PackageInfoEvent { +public: + PackageInfoEvent(); + PackageInfoEvent(const PackageInfoRef& package, + uint32 changes); + PackageInfoEvent(const PackageInfoEvent& other); + virtual ~PackageInfoEvent(); + + bool operator==(const PackageInfoEvent& other); + bool operator!=(const PackageInfoEvent& other); + PackageInfoEvent& operator=(const PackageInfoEvent& other); + + inline const PackageInfoRef& Package() const + { return fPackage; } + + inline uint32 Changes() const + { return fChanges; } + +private: + PackageInfoRef fPackage; + uint32 fChanges; +}; + + +class PackageInfoListener : public BReferenceable { +public: + PackageInfoListener(); + virtual ~PackageInfoListener(); + + virtual void PackageChanged( + const PackageInfoEvent& event) = 0; +}; + + +typedef BReference PackageInfoListenerRef; + + +#endif // PACKAGE_INFO_LISTENER_H diff --git a/src/apps/haiku-depot/PackageInfoView.cpp b/src/apps/haiku-depot/PackageInfoView.cpp index 51b92c51e5..d040ee26d7 100644 --- a/src/apps/haiku-depot/PackageInfoView.cpp +++ b/src/apps/haiku-depot/PackageInfoView.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -1122,12 +1123,77 @@ private: }; +// #pragma mark - PackageInfoViewListener + + +enum { + MSG_UPDATE_PACKAGE = 'updp' +}; + + +class PackageInfoView::Listener : public PackageInfoListener { +public: + Listener(PackageInfoView* view) + : + fView(view) + { + } + + virtual ~Listener() + { + } + + virtual void PackageChanged(const PackageInfoEvent& event) + { + BMessenger messenger(fView); + if (!messenger.IsValid()) + return; + + const PackageInfo& package = *event.Package().Get(); + + BMessage message(MSG_UPDATE_PACKAGE); + message.AddString("title", package.Title()); + message.AddUInt32("changes", event.Changes()); + + messenger.SendMessage(&message); + } + + void SetPackage(const PackageInfoRef& package) + { + if (fPackage == package) + return; + + PackageInfoListenerRef listener(this); + + if (fPackage.Get() != NULL) + fPackage->RemoveListener(listener); + + fPackage = package; + + if (fPackage.Get() != NULL) + fPackage->AddListener(listener); + } + + const PackageInfoRef& Package() const + { + return fPackage; + } + +private: + PackageInfoView* fView; + PackageInfoRef fPackage; +}; + + // #pragma mark - PackageInfoView -PackageInfoView::PackageInfoView(PackageManager* packageManager) +PackageInfoView::PackageInfoView(BLocker* modelLock, + PackageManager* packageManager) : - BGroupView("package info view", B_VERTICAL) + BGroupView("package info view", B_VERTICAL), + fModelLock(modelLock), + fPackageListener(new(std::nothrow) Listener(this)) { fTitleView = new TitleView(); fPackageActionView = new PackageActionView(packageManager); @@ -1150,6 +1216,8 @@ PackageInfoView::PackageInfoView(PackageManager* packageManager) PackageInfoView::~PackageInfoView() { + fPackageListener->SetPackage(PackageInfoRef(NULL)); + delete fPackageListener; } @@ -1163,6 +1231,35 @@ void PackageInfoView::MessageReceived(BMessage* message) { switch (message->what) { + case MSG_UPDATE_PACKAGE: + { + if (fPackageListener->Package().Get() == NULL) + break; + + BString title; + uint32 changes; + if (message->FindString("title", &title) != B_OK + || message->FindUInt32("changes", &changes) != B_OK) { + break; + } + + const PackageInfo& package = *fPackageListener->Package().Get(); + if (package.Title() != title) + break; + + BAutolock _(fModelLock); + + if ((changes & PKG_CHANGED_DESCRIPTION) != 0 + || (changes & PKG_CHANGED_SCREENSHOTS) != 0) { + fTitleView->SetPackage(package); + } + + if ((changes & PKG_CHANGED_RATINGS) != 0) { + fPagesView->SetPackage(package); + } + + break; + } default: BGroupView::MessageReceived(message); break; @@ -1171,14 +1268,20 @@ PackageInfoView::MessageReceived(BMessage* message) void -PackageInfoView::SetPackage(const PackageInfo& package) +PackageInfoView::SetPackage(const PackageInfoRef& packageRef) { + BAutolock _(fModelLock); + + const PackageInfo& package = *packageRef.Get(); + fTitleView->SetPackage(package); fPackageActionView->SetPackage(package); fPagesView->SetPackage(package); if (fPagesView->IsHidden(fPagesView)) fPagesView->Show(); + + fPackageListener->SetPackage(packageRef); } @@ -1191,5 +1294,9 @@ PackageInfoView::Clear() if (!fPagesView->IsHidden(fPagesView)) fPagesView->Hide(); + + BAutolock _(fModelLock); + + fPackageListener->SetPackage(PackageInfoRef(NULL)); } diff --git a/src/apps/haiku-depot/PackageInfoView.h b/src/apps/haiku-depot/PackageInfoView.h index ea871dda36..723fa7a266 100644 --- a/src/apps/haiku-depot/PackageInfoView.h +++ b/src/apps/haiku-depot/PackageInfoView.h @@ -8,8 +8,10 @@ #include #include "PackageInfo.h" +#include "PackageInfoListener.h" +class BLocker; class TitleView; class PackageActionView; class PackageManager; @@ -23,19 +25,27 @@ enum { class PackageInfoView : public BGroupView { public: - PackageInfoView(PackageManager* packageManager); + PackageInfoView(BLocker* modelLock, + PackageManager* packageManager); virtual ~PackageInfoView(); virtual void AttachedToWindow(); virtual void MessageReceived(BMessage* message); - void SetPackage(const PackageInfo& package); + void SetPackage(const PackageInfoRef& package); void Clear(); private: + class Listener; + +private: + BLocker* fModelLock; + TitleView* fTitleView; PackageActionView* fPackageActionView; PagesView* fPagesView; + + Listener* fPackageListener; }; #endif // PACKAGE_INFO_VIEW_H diff --git a/src/apps/haiku-depot/PackageListView.cpp b/src/apps/haiku-depot/PackageListView.cpp index 332a64bf3f..b46fefda15 100644 --- a/src/apps/haiku-depot/PackageListView.cpp +++ b/src/apps/haiku-depot/PackageListView.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -80,13 +81,58 @@ private: class PackageRow : public BRow { typedef BRow Inherited; public: - PackageRow(const PackageInfo& package); + PackageRow(const PackageInfoRef& package, + PackageListener* listener); + virtual ~PackageRow(); - const PackageInfo& Package() const + const PackageInfoRef& Package() const { return fPackage; } + void UpdateRating(); + private: - PackageInfo fPackage; + PackageInfoRef fPackage; + PackageInfoListenerRef fPackageListener; +}; + + +enum { + MSG_UPDATE_PACKAGE = 'updp' +}; + + +class PackageListener : public PackageInfoListener { +public: + PackageListener(PackageListView* view) + : + fView(view) + { + } + + virtual ~PackageListener() + { + } + + virtual void PackageChanged(const PackageInfoEvent& event) + { + if ((event.Changes() & PKG_CHANGED_RATINGS) == 0) + return; + + BMessenger messenger(fView); + if (!messenger.IsValid()) + return; + + const PackageInfo& package = *event.Package().Get(); + + BMessage message(MSG_UPDATE_PACKAGE); + message.AddString("title", package.Title()); + message.AddUInt32("changes", event.Changes()); + + messenger.SendMessage(&message); + } + +private: + PackageListView* fView; }; @@ -374,11 +420,18 @@ enum { }; -PackageRow::PackageRow(const PackageInfo& package) +PackageRow::PackageRow(const PackageInfoRef& packageRef, + PackageListener* packageListener) : Inherited(ceilf(be_plain_font->Size() * 1.8f)), - fPackage(package) + fPackage(packageRef), + fPackageListener(packageListener) { + if (packageRef.Get() == NULL) + return; + + PackageInfo& package = *packageRef.Get(); + // Package icon and title // NOTE: The icon BBitmap is referenced by the fPackage member. const BBitmap* icon = NULL; @@ -387,8 +440,7 @@ PackageRow::PackageRow(const PackageInfo& package) SetField(new BBitmapStringField(icon, package.Title()), kTitleColumn); // Rating - RatingSummary summary = package.CalculateRatingSummary(); - SetField(new RatingField(summary.averageRating), kRatingColumn); + UpdateRating(); // Description SetField(new BStringField(package.ShortDescription()), kDescriptionColumn); @@ -400,6 +452,25 @@ PackageRow::PackageRow(const PackageInfo& package) // Status // TODO: Fetch info about installed/deactivated/unintalled/... SetField(new BStringField("n/a"), kStatusColumn); + + package.AddListener(fPackageListener); +} + + +PackageRow::~PackageRow() +{ + if (fPackage.Get() != NULL) + fPackage->RemoveListener(fPackageListener); +} + + +void +PackageRow::UpdateRating() +{ + if (fPackage.Get() == NULL) + return; + RatingSummary summary = fPackage->CalculateRatingSummary(); + SetField(new RatingField(summary.averageRating), kRatingColumn); } @@ -487,9 +558,11 @@ private: // #pragma mark - PackageListView -PackageListView::PackageListView() +PackageListView::PackageListView(BLocker* modelLock) : - BColumnListView("package list view", 0, B_FANCY_BORDER, true) + BColumnListView("package list view", 0, B_FANCY_BORDER, true), + fModelLock(modelLock), + fPackageListener(new(std::nothrow) PackageListener(this)) { AddColumn(new PackageColumn(B_TRANSLATE("Name"), 150, 50, 300, B_TRUNCATE_MIDDLE), kTitleColumn); @@ -511,6 +584,8 @@ PackageListView::PackageListView() PackageListView::~PackageListView() { + Clear(); + delete fPackageListener; } @@ -525,6 +600,27 @@ void PackageListView::MessageReceived(BMessage* message) { switch (message->what) { + case MSG_UPDATE_PACKAGE: + { + BString title; + uint32 changes; + if (message->FindString("title", &title) != B_OK + || message->FindUInt32("changes", &changes) != B_OK) { + break; + } + + if ((changes & PKG_CHANGED_RATINGS) == 0) + break; + + BAutolock _(fModelLock); + + PackageRow* row = _FindRow(title); + if (row != NULL) + row->UpdateRating(); + + break; + } + default: BColumnListView::MessageReceived(message); break; @@ -539,21 +635,16 @@ PackageListView::SelectionChanged() BMessage message(MSG_PACKAGE_SELECTED); - BRow* selected = CurrentSelection(); - - // TODO: Wrong index, its the visible one (i.e. sorted)! - // Solve by putting an ID for the package in the message instead. - int32 index = -1; + PackageRow* selected = dynamic_cast(CurrentSelection()); if (selected != NULL) - index = IndexOf(selected); - message.AddInt32("index", index); + message.AddString("title", selected->Package()->Title()); Window()->PostMessage(&message); } void -PackageListView::AddPackage(const PackageInfo& package) +PackageListView::AddPackage(const PackageInfoRef& package) { PackageRow* packageRow = _FindRow(package); @@ -561,8 +652,10 @@ PackageListView::AddPackage(const PackageInfo& package) if (packageRow != NULL) return; + BAutolock _(fModelLock); + // create the row for this package - packageRow = new PackageRow(package); + packageRow = new PackageRow(package, fPackageListener); // add the row, parent may be NULL (add at top level) AddRow(packageRow); @@ -575,7 +668,7 @@ PackageListView::AddPackage(const PackageInfo& package) PackageRow* -PackageListView::_FindRow(const PackageInfo& package, PackageRow* parent) +PackageListView::_FindRow(const PackageInfoRef& package, PackageRow* parent) { for (int32 i = CountRows(parent) - 1; i >= 0; i--) { PackageRow* row = dynamic_cast(RowAt(i, parent)); @@ -592,3 +685,24 @@ PackageListView::_FindRow(const PackageInfo& package, PackageRow* parent) return NULL; } + +PackageRow* +PackageListView::_FindRow(const BString& packageTitle, PackageRow* parent) +{ + for (int32 i = CountRows(parent) - 1; i >= 0; i--) { + PackageRow* row = dynamic_cast(RowAt(i, parent)); + if (row != NULL && row->Package().Get() != NULL + && row->Package()->Title() == packageTitle) { + return row; + } + if (CountRows(row) > 0) { + // recurse into child rows + row = _FindRow(packageTitle, row); + if (row != NULL) + return row; + } + } + + return NULL; +} + diff --git a/src/apps/haiku-depot/PackageListView.h b/src/apps/haiku-depot/PackageListView.h index 9ffd5760c1..d9c7f66595 100644 --- a/src/apps/haiku-depot/PackageListView.h +++ b/src/apps/haiku-depot/PackageListView.h @@ -8,11 +8,13 @@ #include #include +#include #include "PackageInfo.h" class PackageRow; +class PackageListener; enum { MSG_PACKAGE_SELECTED = 'pkgs', @@ -21,7 +23,7 @@ enum { class PackageListView : public BColumnListView { public: - PackageListView(); + PackageListView(BLocker* modelLock); virtual ~PackageListView(); virtual void AttachedToWindow(); @@ -29,15 +31,20 @@ public: virtual void SelectionChanged(); - void AddPackage(const PackageInfo& package); + void AddPackage(const PackageInfoRef& package); private: - PackageRow* _FindRow(const PackageInfo& package, + PackageRow* _FindRow(const PackageInfoRef& package, PackageRow* parent = NULL); + PackageRow* _FindRow(const BString& packageTitle, + PackageRow* parent = NULL); + private: class ItemCountView; - + + BLocker* fModelLock; ItemCountView* fItemCountView; + PackageListener* fPackageListener; }; #endif // PACKAGE_LIST_VIEW_H diff --git a/src/bin/makebootable/platform/u-boot/Jamfile b/src/bin/makebootable/platform/u-boot/Jamfile new file mode 100644 index 0000000000..e2e9f95c36 --- /dev/null +++ b/src/bin/makebootable/platform/u-boot/Jamfile @@ -0,0 +1,3 @@ +SubDir HAIKU_TOP src bin makebootable platform u-boot ; + +BinCommand makebootable : makebootable.cpp ; diff --git a/src/bin/makebootable/platform/u-boot/makebootable.cpp b/src/bin/makebootable/platform/u-boot/makebootable.cpp new file mode 100644 index 0000000000..8d3ab2762f --- /dev/null +++ b/src/bin/makebootable/platform/u-boot/makebootable.cpp @@ -0,0 +1,6 @@ +int +main() +{ + return 0; +} + diff --git a/src/bin/network/ifconfig/ifconfig.cpp b/src/bin/network/ifconfig/ifconfig.cpp index e1030558ce..bd36e3c248 100644 --- a/src/bin/network/ifconfig/ifconfig.cpp +++ b/src/bin/network/ifconfig/ifconfig.cpp @@ -105,6 +105,7 @@ static const media_type kMediaTypes[] = { { IFM_100_TX, "100baseTX", "100 MBit, 100BASE-TX" }, { IFM_1000_T, "1000baseT", "1 GBit, 1000BASE-T" }, { IFM_1000_SX, "1000baseSX", "1 GBit, 1000BASE-SX" }, + { IFM_10G_T, "10GbaseT", "10 GBit, 10GBASE-T" }, { -1, NULL, NULL } }, { @@ -1012,4 +1013,3 @@ main(int argc, char** argv) list_interfaces(name); return 0; } - diff --git a/src/data/beos_mime/audio/mpeg b/src/data/beos_mime/audio/mpeg index c23a60db1a..05ba846fdc 100644 --- a/src/data/beos_mime/audio/mpeg +++ b/src/data/beos_mime/audio/mpeg @@ -12,3 +12,5 @@ resource(5, "META:EXTENS") message(234) { "extensions" = "MP3", "type" = "audio/mpeg" }; + +resource(6, "META:SNIFF_RULE") "0.50 (0xfffb|0xfffa|\"ID3\")"; diff --git a/src/kits/interface/ColumnListView.cpp b/src/kits/interface/ColumnListView.cpp index fd5c5747e8..eea89d49f6 100644 --- a/src/kits/interface/ColumnListView.cpp +++ b/src/kits/interface/ColumnListView.cpp @@ -500,9 +500,7 @@ BRow::SetField(BField* field, int32 logicalFieldIndex) if (NULL != fList) { ValidateField(field, logicalFieldIndex); - BRect inv; - fList->GetRowRect(this, &inv); - fList->Invalidate(inv); + Invalidate(); } fFields.AddItem(field, logicalFieldIndex); @@ -530,6 +528,14 @@ BRow::IsSelected() const } +void +BRow::Invalidate() +{ + if (fList != NULL) + fList->InvalidateRow(this); +} + + void BRow::ValidateFields() const { @@ -1340,6 +1346,15 @@ BColumnListView::Clear() } +void +BColumnListView::InvalidateRow(BRow* row) +{ + BRect updateRect; + GetRowRect(row, &updateRect); + fOutlineView->Invalidate(updateRect); +} + + void BColumnListView::SetFont(const BFont* font, uint32 mask) { diff --git a/src/kits/interface/ListView.cpp b/src/kits/interface/ListView.cpp index 5c1b4baa3f..d19cd75b6b 100644 --- a/src/kits/interface/ListView.cpp +++ b/src/kits/interface/ListView.cpp @@ -1037,10 +1037,13 @@ BListView::ScrollToSelection() if (Bounds().Contains(itemFrame)) return; - if (itemFrame.top < Bounds().top) - ScrollTo(itemFrame.left, itemFrame.top); - else - ScrollTo(itemFrame.left, itemFrame.bottom - Bounds().Height()); + float scrollPos = itemFrame.top < Bounds().top ? + itemFrame.top : itemFrame.bottom - Bounds().Height(); + + if (itemFrame.top - scrollPos < Bounds().top) + scrollPos = itemFrame.top; + + ScrollTo(itemFrame.left, scrollPos); } diff --git a/src/preferences/screensaver/ScreenSaverWindow.cpp b/src/preferences/screensaver/ScreenSaverWindow.cpp index 2bd834dcd0..4d4303cc1a 100644 --- a/src/preferences/screensaver/ScreenSaverWindow.cpp +++ b/src/preferences/screensaver/ScreenSaverWindow.cpp @@ -583,8 +583,6 @@ ModulesView::DetachedFromWindow() void ModulesView::AttachedToWindow() { - PopulateScreenSaverList(); - fScreenSaversListView->SetTarget(this); fTestButton->SetTarget(this); fAddButton->SetTarget(this); @@ -594,8 +592,7 @@ ModulesView::AttachedToWindow() void ModulesView::AllAttached() { - fScreenSaversListView->ScrollToSelection(); - // This only works after the list view is attached + PopulateScreenSaverList(); fScreenSaversListView->Invoke(new BMessage(kMsgSaverSelected)); } diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index 9230ba9a18..dbc84fe4eb 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -152,7 +152,7 @@ actions BuildUImageScript1 rule BuildUBootSDImage image : files { Depends $(image) : $(files) ; - SDIMAGE_BLOCK_SIZE on $(image) = 1M ; + SDIMAGE_BLOCK_SIZE on $(image) = 1048576 ; # 1M SDIMAGE_SIZE on $(image) = $(HAIKU_BOARD_SDIMAGE_SIZE) ; SDIMAGE_FDISK on $(image) = $(HOST_SFDISK) ; SDIMAGE_FDISK_SCRIPT on $(image) = diff --git a/src/system/boot/platform/u-boot/devices.cpp b/src/system/boot/platform/u-boot/devices.cpp index 8a77d92713..a1a6916038 100644 --- a/src/system/boot/platform/u-boot/devices.cpp +++ b/src/system/boot/platform/u-boot/devices.cpp @@ -5,10 +5,12 @@ #include -#include + +#include #include -#include +#include #include +#include #define TRACE_DEVICES #ifdef TRACE_DEVICES @@ -73,6 +75,18 @@ platform_add_block_devices(stage2_args *args, NodeList *devicesList) status_t platform_register_boot_device(Node *device) { - TRACE("platform_register_boot_device\n"); + disk_identifier disk_ident; + disk_ident.bus_type = UNKNOWN_BUS; + disk_ident.device_type = UNKNOWN_DEVICE; + disk_ident.device.unknown.size = device->Size(); + + for (int32 i = 0; i < NUM_DISK_CHECK_SUMS; i++) { + disk_ident.device.unknown.check_sums[i].offset = -1; + disk_ident.device.unknown.check_sums[i].sum = 0; + } + + gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, + &disk_ident, sizeof(disk_ident)); + return B_OK; } diff --git a/src/system/boot/platform/u-boot/uimage.cpp b/src/system/boot/platform/u-boot/uimage.cpp index dfe85a4242..0e2edd5c0e 100644 --- a/src/system/boot/platform/u-boot/uimage.cpp +++ b/src/system/boot/platform/u-boot/uimage.cpp @@ -55,7 +55,7 @@ image_multi_getimg(struct image_header *image, uint32 idx, uint32 *data, uint32 *size = ntohl(sizes[i]); return true; } - base += ntohl(sizes[i]); + base += (ntohl(sizes[i]) + 3) & ~3; } return false; } diff --git a/src/system/kernel/arch/arm/arch_asm.S b/src/system/kernel/arch/arm/arch_asm.S index eb570a5f90..689f615646 100644 --- a/src/system/kernel/arch/arm/arch_asm.S +++ b/src/system/kernel/arch/arm/arch_asm.S @@ -227,8 +227,8 @@ FUNCTION(arch_debug_call_with_fault_handler): // Set fault handler address, and fault handler stack pointer address. We // don't need to save the previous values, since that's done by the caller. ldr r4, =1f - str r4, [ r0, #CPU_ENT_fault_handler ] - str sp, [ r0, #CPU_ENT_fault_handler_stack_pointer ] + str r4, [r0, #CPU_ENT_fault_handler] + str sp, [r0, #CPU_ENT_fault_handler_stack_pointer] mov r4, r1 // call the function diff --git a/src/system/kernel/arch/arm/arch_timer.cpp b/src/system/kernel/arch/arm/arch_timer.cpp index 5cf8574279..6c291ed6bb 100644 --- a/src/system/kernel/arch/arm/arch_timer.cpp +++ b/src/system/kernel/arch/arm/arch_timer.cpp @@ -35,35 +35,63 @@ #define PXA_OSSR 0x05 #define PXA_OIER 0x07 #define PXA_OSCR4 0x10 +#define PXA_OSCR5 0x11 #define PXA_OSMR4 0x20 +#define PXA_OSMR5 0x21 #define PXA_OMCR4 0x30 +#define PXA_OMCR5 0x31 +#define PXA_RES_S (3 << 0) +#define PXA_RES_MS (1 << 1) +#define PXA_RES_US (1 << 2) -static area_id sPxaTimersArea; -static uint32 *sPxaTimersBase; +#define US2S(bt) ((bt) / 1000000ULL) +#define US2MS(bt) ((bt) / 1000ULL) +static area_id sPxaTimersArea = B_ERROR; +static uint32 *sPxaTimersBase = NULL; +static bigtime_t sSystemTime = 0; static int32 pxa_timer_interrupt(void *data) { - int32 ret = timer_interrupt(); - sPxaTimersBase[PXA_OSSR] |= (1 << 4); + if (sPxaTimersBase[PXA_OSSR] & (1 << 4)) { + sPxaTimersBase[PXA_OSSR] |= (1 << 4); + return timer_interrupt(); + } - return ret; + if (sPxaTimersBase[PXA_OSSR] & (1 << 5)) { + sPxaTimersBase[PXA_OSSR] |= (1 << 5); + sSystemTime += UINT_MAX + 1ULL; + } + + return B_HANDLED_INTERRUPT; } - void arch_timer_set_hardware_timer(bigtime_t timeout) { - TRACE(("arch_timer_set_hardware_timer(%lld)\n", timeout)); + uint32 val = timeout & UINT_MAX; + uint32 res = PXA_RES_US; - if (sPxaTimersBase) { - sPxaTimersBase[PXA_OIER] |= (1 << 4); - sPxaTimersBase[PXA_OMCR4] = 4; // set to exactly single milisecond resolution - sPxaTimersBase[PXA_OSMR4] = timeout; - sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again + if (timeout & ~UINT_MAX) { + // Does not fit, so scale resolution down to milliseconds + if (US2MS(timeout) & ~UINT_MAX) { + // Still does not fit, scale down to seconds as last ditch attempt + val = US2S(timeout) & UINT_MAX; + res = PXA_RES_S; + } else { + // Fits in millisecond resolution + val = US2MS(timeout) & UINT_MAX; + res = PXA_RES_MS; + } } + + TRACE(("arch_timer_set_hardware_timer(val=%lu, res=%lu)\n", val, res)); + sPxaTimersBase[PXA_OIER] |= (1 << 4); + sPxaTimersBase[PXA_OMCR4] = res; + sPxaTimersBase[PXA_OSMR4] = val; + sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again } @@ -72,13 +100,10 @@ arch_timer_clear_hardware_timer() { TRACE(("arch_timer_clear_hardware_timer\n")); - if (sPxaTimersBase) { - sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer - sPxaTimersBase[PXA_OIER] &= ~(4 << 1); - } + sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer + sPxaTimersBase[PXA_OIER] &= ~(1 << 4); } - int arch_init_timer(kernel_args *args) { @@ -88,9 +113,20 @@ arch_init_timer(kernel_args *args) if (sPxaTimersArea < 0) return sPxaTimersArea; - sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer + sPxaTimersBase[PXA_OIER] |= (1 << 5); // enable timekeeping timer + sPxaTimersBase[PXA_OMCR5] = PXA_RES_US | (1 << 7); + sPxaTimersBase[PXA_OSMR5] = UINT_MAX; + sPxaTimersBase[PXA_OSCR5] = 0; install_io_interrupt_handler(PXA_TIMERS_INTERRUPT, &pxa_timer_interrupt, NULL, 0); return B_OK; } + +bigtime_t +system_time(void) +{ + return (sPxaTimersBase != NULL) ? + sSystemTime + sPxaTimersBase[PXA_OSCR5] : + 0ULL; +} diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 67212e2e17..a817ec05b7 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -753,15 +753,6 @@ 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; } diff --git a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp index b560db08c8..2a6ef7986d 100644 --- a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp +++ b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp @@ -60,10 +60,8 @@ X86PagingMethod64Bit::Init(kernel_args* args, 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); - } + if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) + call_all_cpus_sync(&_EnableExecutionDisable, NULL); // Ensure that the user half of the address space is clear. This removes // the temporary identity mapping made by the boot loader. @@ -384,3 +382,11 @@ X86PagingMethod64Bit::PutPageTableEntryInTable(uint64* entry, SetTableEntry(entry, page); } + +/*static*/ void +X86PagingMethod64Bit::_EnableExecutionDisable(void* dummy, int cpu) +{ + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) + | IA32_MSR_EFER_NX); +} + diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp index f8b471279d..6e1da996c2 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp +++ b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp @@ -149,10 +149,8 @@ struct X86PagingMethodPAE::ToPAESwitcher { 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); - } + if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) + call_all_cpus_sync(&_EnableExecutionDisable, NULL); // set return values _virtualPDPT = pdpt; @@ -173,6 +171,12 @@ private: x86_write_cr4(x86_read_cr4() | IA32_CR4_PAE | IA32_CR4_GLOBAL_PAGES); } + static void _EnableExecutionDisable(void* dummy, int cpu) + { + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) + | IA32_MSR_EFER_NX); + } + void _TranslatePageTable(addr_t virtualBase) { page_table_entry* entry = &fPageHole[virtualBase / B_PAGE_SIZE]; diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp index e73c025e95..5de0b31d71 100644 --- a/src/system/kernel/device_manager/device_manager.cpp +++ b/src/system/kernel/device_manager/device_manager.cpp @@ -2280,7 +2280,6 @@ device_manager_init(struct kernel_args* args) dm_init_io_resources(); recursive_lock_init(&sLock, "device manager"); - init_node_tree(); register_generic_syscall(DEVICE_MANAGER_SYSCALLS, control_device_manager, 1, 0); @@ -2300,6 +2299,9 @@ device_manager_init(struct kernel_args* args) "dump an I/O operation"); add_debugger_command("io_buffer", &dump_io_buffer, "dump an I/O buffer"); add_debugger_command("dma_buffer", &dump_dma_buffer, "dump a DMA buffer"); + + init_node_tree(); + return B_OK; } diff --git a/src/system/kernel/lib/arch/arm/Jamfile b/src/system/kernel/lib/arch/arm/Jamfile index 084a552ca8..1bdf0f1501 100644 --- a/src/system/kernel/lib/arch/arm/Jamfile +++ b/src/system/kernel/lib/arch/arm/Jamfile @@ -11,8 +11,6 @@ SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ; KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o : atomic.S byteorder.S -# system_time_asm.S - system_time.c generic_system_time_nsecs.cpp diff --git a/src/system/libroot/os/arch/arm/atomic.S b/src/system/libroot/os/arch/arm/atomic.S index 0127fd03e8..795e89961d 100644 --- a/src/system/libroot/os/arch/arm/atomic.S +++ b/src/system/libroot/os/arch/arm/atomic.S @@ -164,83 +164,36 @@ FUNCTION(atomic_get): bx lr FUNCTION_END(atomic_get) +FUNCTION(__sync_fetch_and_add_4): + bx lr +FUNCTION_END(__sync_fetch_and_add_4) /* int64 atomic_add64(vint64 *value, int64 addValue) */ -//FUNCTION(atomic_add64): -// movem.l %d2-%d3/%a2,-(%a7) -// move.l (4,%a7),%a2 -// lea.l (4,%a2),%a1 -// // addValue -// move.l (12,%a7),%d3 /*LSB*/ -// move.l (8,%a7),%d2 /*MSB*/ -//miss5: // old value -// move.l (%a1),%d1 /*LSB*/ -// move.l (%a2),%d0 /*MSB*/ -// add.l %d1,%d3 -// addx.l %d0,%d2 -// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1) -// bne miss5 -// // return value d0:d1 -// movem.l (%a7)+,%d2-%d3/%a2 -// rts -//FUNCTION_END(atomic_add64) +FUNCTION(atomic_add64): + bx lr +FUNCTION_END(atomic_add64) /* int64 atomic_and64(vint64 *value, int64 andValue) */ -//FUNCTION(atomic_and64): -//FUNCTION_END(atomic_and64) +FUNCTION(atomic_and64): + bx lr +FUNCTION_END(atomic_and64) /* int64 atomic_or64(vint64 *value, int64 orValue) */ -//FUNCTION(atomic_or64): -//FUNCTION_END(atomic_or64) +FUNCTION(atomic_or64): + bx lr +FUNCTION_END(atomic_or64) /* int64 atomic_set64(vint64 *value, int64 newValue) */ -//FUNCTION(atomic_set64): -// movem.l %d2-%d3/%a2,-(%a7) -// move.l (4,%a7),%a2 -// lea.l (4,%a2),%a1 -// // new value -// move.l (12,%a7),%d3 /*LSB*/ -// move.l (8,%a7),%d2 /*MSB*/ -// // old value -// move.l (%a1),%d1 /*LSB*/ -// move.l (%a2),%d0 /*MSB*/ -//miss8: cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1) -// bne miss8 -// // return value d0:d1 -// movem.l (%a7)+,%d2-%d3/%a2 -// rts -//FUNCTION_END(atomic_set64) +FUNCTION(atomic_set64): + bx lr +FUNCTION_END(atomic_set64) /* int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) */ -//FUNCTION(atomic_test_and_set64): -// movem.l %d2-%d3/%a2,-(%a7) -// move.l (4,%a7),%a2 -// lea.l (4,%a2),%a1 -// // new value -// move.l (12,%a7),%d3 /*LSB*/ -// move.l (8,%a7),%d2 /*MSB*/ -// // test against value -// move.l (20,%a7),%d1 /*LSB*/ -// move.l (16,%a7),%d0 /*MSB*/ -// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1) -// // return value d0:d1 -// movem.l (%a7)+,%d2-%d3/%a2 -// rts -//FUNCTION_END(atomic_test_and_set64) +FUNCTION(atomic_test_and_set64): + bx lr +FUNCTION_END(atomic_test_and_set64) /* int64 atomic_get64(vint64 *value) */ -//FUNCTION(atomic_get64): -// movem.l %d2-%d3/%a2,-(%a7) -// move.l (4,%a7),%a2 -// lea.l (4,%a2),%a1 -// move.l (%a1),%d1 /*LSB*/ -// move.l (%a2),%d0 /*MSB*/ -// move.l %d1,%d3 -// move.l %d0,%d2 -// // we must use cas... so we change to the same value if matching, -// // else we get the correct one anyway -// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1) -// // return value -// movem.l (%a7)+,%d2-%d3/%a2 -// rts -//FUNCTION_END(atomic_get64) +FUNCTION(atomic_get64): + bx lr +FUNCTION_END(atomic_get64) diff --git a/src/system/libroot/posix/pthread/pthread_attr.c b/src/system/libroot/posix/pthread/pthread_attr.c index f6a15ff5e6..fecb9fca5b 100644 --- a/src/system/libroot/posix/pthread/pthread_attr.c +++ b/src/system/libroot/posix/pthread/pthread_attr.c @@ -12,6 +12,8 @@ #include #include +#include + #include @@ -105,6 +107,8 @@ pthread_attr_setstacksize(pthread_attr_t *_attr, size_t stacksize) if (_attr == NULL || (attr = *_attr) == NULL) return B_BAD_VALUE; + STATIC_ASSERT(PTHREAD_STACK_MIN >= MIN_USER_STACK_SIZE + && PTHREAD_STACK_MIN <= MAX_USER_STACK_SIZE); if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE) return B_BAD_VALUE; diff --git a/src/tools/makebootable/platform/u-boot/Jamfile b/src/tools/makebootable/platform/u-boot/Jamfile new file mode 100644 index 0000000000..eac99f00d3 --- /dev/null +++ b/src/tools/makebootable/platform/u-boot/Jamfile @@ -0,0 +1,12 @@ +SubDir HAIKU_TOP src tools makebootable platform u-boot ; + +SEARCH_SOURCE + += [ FDirName $(HAIKU_TOP) src bin makebootable platform u-boot ] ; + +BuildPlatformMain makebootable : + makebootable.cpp + $(hostPlatformSources) + : $(HOST_LIBBE) $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) +; + +BuildPlatformMain makebootable : makebootable.cpp : $(HOST_LIBSTDC++) ; diff --git a/src/tools/translation/bitsinfo/Jamfile b/src/tools/translation/bitsinfo/Jamfile index 50b011f5a5..eca781ef8a 100644 --- a/src/tools/translation/bitsinfo/Jamfile +++ b/src/tools/translation/bitsinfo/Jamfile @@ -1,4 +1,13 @@ SubDir HAIKU_TOP src tools translation bitsinfo ; -BinCommand bitsinfo : bitsinfo.cpp : be $(TARGET_LIBSUPC++) ; +BinCommand bitsinfo : + bitsinfo.cpp + : be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ; +AddResources bitsinfo : bitsinfo.rdef ; + +DoCatalogs bitsinfo : + x-vnd.Haiku-bitsinfo + : + bitsinfo.cpp +; diff --git a/src/tools/translation/bitsinfo/bitsinfo.cpp b/src/tools/translation/bitsinfo/bitsinfo.cpp index 7446228b86..81a1328ca4 100644 --- a/src/tools/translation/bitsinfo/bitsinfo.cpp +++ b/src/tools/translation/bitsinfo/bitsinfo.cpp @@ -38,10 +38,14 @@ #include #include #include +#include #include #include #include +#undef B_TRANSLATE_CONTEXT +#define B_TRANSLATE_CONTEXT "bitsinfo" + struct ColorSpaceName { color_space id; const char *name; @@ -62,7 +66,8 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) // read in the rest of the header ssize_t size = sizeof(TranslatorBitmap); if (file.Read(reinterpret_cast (&header), size) != size) { - printf("\nError: Unable to read the Be bitmap header.\n"); + printf(B_TRANSLATE("\nError: Unable to read the Be bitmap " + "header.\n")); return; } if (!bdumppixels) @@ -72,28 +77,29 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) // convert to host byte order if (swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap), B_SWAP_BENDIAN_TO_HOST) != B_OK) { - printf("\nError: Unable to swap byte order\n"); + printf(B_TRANSLATE("\nError: Unable to swap byte order\n")); return; } - printf("\nBe bitmap (\"bits\") header for: %s\n\n", filepath); + printf(B_TRANSLATE("\nBe bitmap (\"bits\") header for: %s\n\n"), + filepath); const uint32 kbitsmagic = 0x62697473UL; // in ASCII, this number looks like "bits" - printf("magic number: 0x%.8lx ", header.magic); if (header.magic == kbitsmagic) - printf("(valid)\n"); + printf(B_TRANSLATE("magic number: 0x%.8lx (valid)\n"), + header.magic); else - printf("(INVALID, should be: 0x%.8lx)\n", - kbitsmagic); - printf("bounds: (%f, %f, %f, %f)\n", + printf(B_TRANSLATE("magic number: 0x%.8lx (INVALID, should be: " + "0x%.8lx)\n"), header.magic, kbitsmagic); + printf(B_TRANSLATE("bounds: (%f, %f, %f, %f)\n"), header.bounds.left, header.bounds.top, header.bounds.right, header.bounds.bottom); - printf("dimensions: %d x %d\n", + printf(B_TRANSLATE("dimensions: %d x %d\n"), static_cast(header.bounds.Width() + 1), static_cast(header.bounds.Height() + 1)); - printf("bytes per row: %u\n", + printf(B_TRANSLATE("bytes per row: %u\n"), static_cast(header.rowBytes)); // print out colorspace if it matches an item in the list @@ -149,15 +155,15 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) int32 i; for (i = 0; i < kncolorspaces; i++) { if (header.colors == colorspaces[i].id) { - printf("color space: %s\n", colorspaces[i].name); + printf(B_TRANSLATE("color space: %s\n"), colorspaces[i].name); break; } } if (i == kncolorspaces) - printf("color space: Unknown (0x%.8lx)\n", + printf(B_TRANSLATE("color space: Unknown (0x%.8lx)\n"), static_cast(header.colors)); - printf("data size: %u\n", + printf(B_TRANSLATE("data size: %u\n"), static_cast(header.dataSize)); if (bdumppixels) { @@ -178,18 +184,19 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) break; default: - printf("Sorry, %s isn't supported yet" - " for this color space\n", kpixels); + printf(B_TRANSLATE("Sorry, %s isn't supported yet" + " for this color space\n"), kpixels); return; } uint8 *prow = new uint8[header.rowBytes]; if (!prow) { - printf("Error: Not enough memory for row buffer\n"); + printf(B_TRANSLATE("Error: Not enough memory for row " + "buffer\n")); return; } ssize_t ret, n; uint32 totalbytes = 0; - printf("pixel data (%s):\n", components); + printf(B_TRANSLATE("pixel data (%s):\n"), components); while ((ret = file.Read(prow, header.rowBytes)) > 0) { n = 0; while (n < ret) { @@ -205,18 +212,21 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) } } else - printf("Error opening %s\n", filepath); + printf(B_TRANSLATE_COMMENT("Error opening %s\n", + "file path is opening"), filepath); } int main(int argc, char **argv) { if (argc == 1) { - printf("\nbitsinfo - reports information about a Be bitmap (\"bits\") image\n"); - printf("\nUsage:\n"); - printf("bitsinfo [options] filename.bits\n\n"); - printf("Options:\n\n"); - printf("\t%s \t print RGB color for each pixel\n", kpixels); + printf(B_TRANSLATE("\nbitsinfo - reports information about a Be " + "bitmap (\"bits\") image\n")); + printf(B_TRANSLATE("\nUsage:\n")); + printf(B_TRANSLATE("bitsinfo [options] filename.bits\n\n")); + printf(B_TRANSLATE("Options:\n\n")); + printf(B_TRANSLATE("\t%s \t print RGB color for each pixel\n"), + kpixels); } else { int32 first = 1; diff --git a/src/tools/translation/bitsinfo/bitsinfo.rdef b/src/tools/translation/bitsinfo/bitsinfo.rdef new file mode 100644 index 0000000000..935e1e038a --- /dev/null +++ b/src/tools/translation/bitsinfo/bitsinfo.rdef @@ -0,0 +1,17 @@ +/* + * bitsinfo.rdef + */ + +resource app_signature "application/x-vnd.Haiku-bitsinfo"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "bitsinfo displays text information about Be bitmap format ("bits") images.", + long_info = "Haiku bitsinfo is a command line tool for displaying text information about Be bitmap format ("bits") images. Written by Michael Wilber, OBOS Translation Kit Team, Copyright © 2003 OpenBeOS Project." +}; + +resource app_flags B_SINGLE_LAUNCH; diff --git a/src/tools/translation/bmpinfo/Jamfile b/src/tools/translation/bmpinfo/Jamfile index 584b9a15cf..fae0e01048 100644 --- a/src/tools/translation/bmpinfo/Jamfile +++ b/src/tools/translation/bmpinfo/Jamfile @@ -1,4 +1,11 @@ SubDir HAIKU_TOP src tools translation bmpinfo ; -BinCommand bmpinfo : bmpinfo.cpp : be ; +BinCommand bmpinfo : bmpinfo.cpp : be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ; +AddResources bmpinfo : bmpinfo.rdef ; + +DoCatalogs bmpinfo : + x-vnd.Haiku-bmpsinfo + : + bmpinfo.cpp +; diff --git a/src/tools/translation/bmpinfo/bmpinfo.cpp b/src/tools/translation/bmpinfo/bmpinfo.cpp index b5eb0d7038..c5e7a516c0 100644 --- a/src/tools/translation/bmpinfo/bmpinfo.cpp +++ b/src/tools/translation/bmpinfo/bmpinfo.cpp @@ -36,10 +36,14 @@ #include #include #include +#include #include #include #include +#undef B_TRANSLATE_CONTEXT +#define B_TRANSLATE_CONTEXT "bmpinfo" + #define BMP_NO_COMPRESS 0 #define BMP_RLE8_COMPRESS 1 #define BMP_RLE4_COMPRESS 2 @@ -82,7 +86,7 @@ print_bmp_info(BFile &file) ssize_t size = 14; if (file.Read(buf, size) != size) { - printf("Error: unable to read BMP file header\n"); + printf(B_TRANSLATE("Error: unable to read BMP file header\n")); return; } @@ -96,16 +100,18 @@ print_bmp_info(BFile &file) swap_data(B_UINT32_TYPE, (reinterpret_cast (&fh)) + 2, 12, B_SWAP_LENDIAN_TO_HOST); - printf("\nFile Header:\n"); - printf(" magic: 0x%.4x (should be: 0x424d)\n", fh.magic); - printf(" file size: 0x%.8lx (%lu)\n", fh.fileSize, fh.fileSize); - printf(" reserved: 0x%.8lx (should be: 0x%.8x)\n", fh.reserved, 0); - printf("data offset: 0x%.8lx (%lu) (should be: >= 54 for MS format " - "and >= 26 for OS/2 format)\n", fh.dataOffset, fh.dataOffset); + printf(B_TRANSLATE("\nFile Header:\n")); + printf(B_TRANSLATE(" magic: 0x%.4x (should be: 0x424d)\n"), fh.magic); + printf(B_TRANSLATE(" file size: 0x%.8lx (%lu)\n"), fh.fileSize, + fh.fileSize); + printf(B_TRANSLATE(" reserved: 0x%.8lx (should be: 0x%.8x)\n"), + fh.reserved, 0); + printf(B_TRANSLATE("data offset: 0x%.8lx (%lu) (should be: >= 54 for MS " + "format and >= 26 for OS/2 format)\n"), fh.dataOffset, fh.dataOffset); uint32 headersize = 0; if (file.Read(&headersize, 4) != 4) { - printf("Error: unable to read info header size\n"); + printf(B_TRANSLATE("Error: unable to read info header size\n")); return; } swap_data(B_UINT32_TYPE, &headersize, 4, B_SWAP_LENDIAN_TO_HOST); @@ -115,7 +121,7 @@ print_bmp_info(BFile &file) MSInfoHeader msh; msh.size = headersize; if (file.Read(reinterpret_cast (&msh) + 4, 36) != 36) { - printf("Error: unable to read entire MS info header\n"); + printf(B_TRANSLATE("Error: unable to read entire MS info header\n")); return; } @@ -123,22 +129,33 @@ print_bmp_info(BFile &file) swap_data(B_UINT32_TYPE, reinterpret_cast (&msh) + 4, 36, B_SWAP_LENDIAN_TO_HOST); - printf("\nMS Info Header:\n"); - printf(" header size: 0x%.8lx (%lu) (should be: 40)\n", msh.size, msh.size); - printf(" width: %lu\n", msh.width); - printf(" height: %lu\n", msh.height); - printf(" planes: %u (should be: 1)\n", msh.planes); - printf(" bits per pixel: %u (should be: 1,4,8,16,24 or 32)\n", msh.bitsperpixel); - printf(" compression: %s (%lu)\n", - ((msh.compression == BMP_NO_COMPRESS) ? ("none") : - ((msh.compression == BMP_RLE8_COMPRESS) ? ("RLE 8") : - ((msh.compression == BMP_RLE4_COMPRESS) ? ("RLE 4") : - ("unknown")))), msh.compression); - printf(" image size: 0x%.8lx (%lu)\n", msh.imagesize, msh.imagesize); - printf(" x pixels/meter: %lu\n", msh.xpixperm); - printf(" y pixels/meter: %lu\n", msh.ypixperm); - printf(" colors used: %lu\n", msh.colorsused); - printf("colors important: %lu\n", msh.colorsimportant); + printf(B_TRANSLATE("\nMS Info Header:\n")); + printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: " + "40)\n"), msh.size, msh.size); + printf(B_TRANSLATE(" width: %lu\n"), msh.width); + printf(B_TRANSLATE(" height: %lu\n"), msh.height); + printf(B_TRANSLATE(" planes: %u (should be: 1)\n"), + msh.planes); + printf(B_TRANSLATE(" bits per pixel: %u (should be: 1,4,8,16,24 or " + "32)\n"), msh.bitsperpixel); + if (msh.compression == BMP_NO_COMPRESS) + printf(B_TRANSLATE(" compression: none (%lu)\n"), + msh.compression); + else if (msh.compression == BMP_RLE8_COMPRESS) + printf(B_TRANSLATE(" compression: RLE8 (%lu)\n"), + msh.compression); + else if (msh.compression == BMP_RLE4_COMPRESS) + printf(B_TRANSLATE(" compression: RLE4 (%lu)\n"), + msh.compression); + else + printf(B_TRANSLATE(" compression: unknown (%lu)\n"), + msh.compression); + printf(B_TRANSLATE(" image size: 0x%.8lx (%lu)\n"), msh.imagesize, + msh.imagesize); + printf(B_TRANSLATE(" x pixels/meter: %lu\n"), msh.xpixperm); + printf(B_TRANSLATE(" y pixels/meter: %lu\n"), msh.ypixperm); + printf(B_TRANSLATE(" colors used: %lu\n"), msh.colorsused); + printf(B_TRANSLATE("colors important: %lu\n"), msh.colorsimportant); } else if (headersize == sizeof(OS2InfoHeader)) { // OS/2 format @@ -146,7 +163,8 @@ print_bmp_info(BFile &file) OS2InfoHeader os2; os2.size = headersize; if (file.Read(reinterpret_cast (&os2) + 4, 8) != 8) { - printf("Error: unable to read entire OS/2 info header\n"); + printf(B_TRANSLATE("Error: unable to read entire OS/2 info " + "header\n")); return; } @@ -154,17 +172,18 @@ print_bmp_info(BFile &file) swap_data(B_UINT32_TYPE, reinterpret_cast (&os2) + 4, 8, B_SWAP_LENDIAN_TO_HOST); - printf("\nOS/2 Info Header:\n"); - printf(" header size: 0x%.8lx (%lu) (should be: 12)\n", os2.size, os2.size); - printf(" width: %u\n", os2.width); - printf(" height: %u\n", os2.height); - printf(" planes: %u (should be: 1)\n", os2.planes); - printf("bits per pixel: %u (should be: 1,4,8 or 24)\n", + printf(B_TRANSLATE("\nOS/2 Info Header:\n")); + printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: 12)\n"), + os2.size, os2.size); + printf(B_TRANSLATE(" width: %u\n"), os2.width); + printf(B_TRANSLATE(" height: %u\n"), os2.height); + printf(B_TRANSLATE(" planes: %u (should be: 1)\n"), os2.planes); + printf(B_TRANSLATE("bits per pixel: %u (should be: 1,4,8 or 24)\n"), os2.bitsperpixel); } else - printf("Error: info header size (%lu) does not match MS or OS/2 " - "info header size\n", headersize); + printf(B_TRANSLATE("Error: info header size (%lu) does not match MS " + "or OS/2 info header size\n"), headersize); } int @@ -173,18 +192,20 @@ main(int argc, char **argv) printf("\n"); if (argc == 1) { - printf("bmpinfo - reports information about a BMP image file\n"); - printf("\nUsage:\n"); - printf("bmpinfo filename.bmp\n"); + printf(B_TRANSLATE("bmpinfo - reports information about a BMP image " + "file\n")); + printf(B_TRANSLATE("\nUsage:\n")); + printf(B_TRANSLATE("bmpinfo filename.bmp\n")); } else { BFile file; for (int32 i = 1; i < argc; i++) { if (file.SetTo(argv[i], B_READ_ONLY) != B_OK) - printf("\nError opening %s\n", argv[i]); + printf(B_TRANSLATE("\nError opening %s\n"), argv[i]); else { - printf("\nBMP image information for: %s\n", argv[i]); + printf(B_TRANSLATE("\nBMP image information for: %s\n"), + argv[i]); print_bmp_info(file); } } diff --git a/src/tools/translation/bmpinfo/bmpinfo.rdef b/src/tools/translation/bmpinfo/bmpinfo.rdef new file mode 100644 index 0000000000..90e61483c4 --- /dev/null +++ b/src/tools/translation/bmpinfo/bmpinfo.rdef @@ -0,0 +1,17 @@ +/* + * bmpinfo.rdef + */ + +resource app_signature "application/x-vnd.Haiku-bmpinfo"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "bmpinfo displays text information about BMP images.", + long_info = "Haiku bmpinfo is a command line tool for displaying text information about BMP images. Written by Michael Wilber, OBOS Translation Kit Team, Copyright © 2003 OpenBeOS Project." +}; + +resource app_flags B_SINGLE_LAUNCH; diff --git a/src/tools/translation/tgainfo/Jamfile b/src/tools/translation/tgainfo/Jamfile index 39e8a88dc1..b4b5eb4ddc 100644 --- a/src/tools/translation/tgainfo/Jamfile +++ b/src/tools/translation/tgainfo/Jamfile @@ -1,4 +1,13 @@ SubDir HAIKU_TOP src tools translation tgainfo ; -BinCommand tgainfo : tgainfo.cpp : be ; +BinCommand tgainfo : + tgainfo.cpp + : be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ; +AddResources tgainfo : tgainfo.rdef ; + +DoCatalogs tgainfo : + x-vnd.Haiku-tgainfo + : + tgainfo.cpp +; diff --git a/src/tools/translation/tgainfo/tgainfo.cpp b/src/tools/translation/tgainfo/tgainfo.cpp index e3036f5fc2..925c35e97e 100644 --- a/src/tools/translation/tgainfo/tgainfo.cpp +++ b/src/tools/translation/tgainfo/tgainfo.cpp @@ -36,10 +36,14 @@ #include #include #include +#include #include #include #include +#undef B_TRANSLATE_CONTEXT +#define B_TRANSLATE_CONTEXT "tgainfo" + #define max(x,y) ((x > y) ? x : y) #define DATA_BUFFER_SIZE 64 @@ -99,8 +103,8 @@ const char * colormaptype(uint8 n) { switch (n) { - case 0: return "No colormap"; - case 1: return "colormap"; + case 0: return B_TRANSLATE("No colormap"); + case 1: return B_TRANSLATE("colormap"); } return "unknown"; } @@ -109,15 +113,16 @@ const char * imagetype(uint8 n) { switch (n) { - case 0: return "No Image Data"; - case 1: return "colormap"; - case 2: return "true color"; - case 3: return "grayscale"; - case 9: return "RLE colormap"; - case 10: return "RLE true color"; - case 11: return "RLE grayscale"; + case 0: return B_TRANSLATE("No Image Data"); + case 1: return B_TRANSLATE("colormap"); + case 2: return B_TRANSLATE("true color"); + case 3: return B_TRANSLATE("grayscale"); + case 9: return B_TRANSLATE("RLE colormap"); + case 10: return B_TRANSLATE("RLE true color"); + case 11: return B_TRANSLATE("RLE grayscale"); + default: break; } - return "unknown"; + return B_TRANSLATE("unknown"); } uint16 @@ -140,7 +145,7 @@ print_tga_info(BFile &file) // read in TGA headers ssize_t size = TGA_HEADERS_SIZE; if (size > 0 && file.Read(buf, size) != size) { - printf("Error: unable to read all TGA headers\n"); + printf(B_TRANSLATE("Error: unable to read all TGA headers\n")); return; } @@ -150,12 +155,15 @@ print_tga_info(BFile &file) fh.colormaptype = buf[1]; fh.imagetype = buf[2]; - printf("\nFile Header:\n"); - printf(" id length: %d\n", fh.idlength); + printf(B_TRANSLATE("\nFile Header:\n")); + printf(B_TRANSLATE(" id length: %d\n"), static_cast(fh.idlength)); - printf("colormap type: %d (%s)\n", fh.colormaptype, - colormaptype(fh.colormaptype)); - printf(" image type: %d (%s)\n", fh.imagetype, imagetype(fh.imagetype)); + printf(B_TRANSLATE("colormap type: %d (%s)\n"), + static_cast(fh.colormaptype), + static_cast(colormaptype(fh.colormaptype))); + printf(B_TRANSLATE(" image type: %d (%s)\n"), + static_cast(fh.imagetype), + static_cast(imagetype(fh.imagetype))); // TGA color map spec @@ -164,10 +172,13 @@ print_tga_info(BFile &file) mapspec.length = tga_uint16(reinterpret_cast(buf), 5); mapspec.entrysize = buf[7]; - printf("\nColormap Spec:\n"); - printf("first entry: %d\n", mapspec.firstentry); - printf(" length: %d\n", mapspec.length); - printf(" entry size: %d\n", mapspec.entrysize); + printf(B_TRANSLATE("\nColormap Spec:\n")); + printf(B_TRANSLATE("first entry: %d\n"), + static_cast(mapspec.firstentry)); + printf(B_TRANSLATE(" length: %d\n"), + static_cast(mapspec.length)); + printf(B_TRANSLATE(" entry size: %d\n"), + static_cast(mapspec.entrysize)); // TGA image spec @@ -179,20 +190,47 @@ print_tga_info(BFile &file) imagespec.depth = buf[16]; imagespec.descriptor = buf[17]; - printf("\nImage Spec:\n"); - printf(" x origin: %d\n", imagespec.xorigin); - printf(" y origin: %d\n", imagespec.yorigin); - printf(" width: %d\n", imagespec.width); - printf(" height: %d\n", imagespec.height); - printf(" depth: %d\n", imagespec.depth); - printf("descriptor: 0x%.2x\n", imagespec.descriptor); - printf("\talpha (attr): %d\n", - imagespec.descriptor & TGA_DESC_ALPHABITS); - printf("\t origin: %d (%s %s)\n", - imagespec.descriptor & (TGA_ORIGIN_VERT_BIT | TGA_ORIGIN_HORZ_BIT), - ((imagespec.descriptor & TGA_ORIGIN_VERT_BIT) ? "top" : "bottom"), - ((imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) ? "right" : "left")); - printf("\t bits 7 & 6: %d\n", imagespec.descriptor & TGA_DESC_BITS76); + printf(B_TRANSLATE("\nImage Spec:\n")); + printf(B_TRANSLATE(" x origin: %d\n"), + static_cast(imagespec.xorigin)); + printf(B_TRANSLATE(" y origin: %d\n"), + static_cast(imagespec.yorigin)); + printf(B_TRANSLATE(" width: %d\n"), + static_cast(imagespec.width)); + printf(B_TRANSLATE(" height: %d\n"), + static_cast(imagespec.height)); + printf(B_TRANSLATE(" depth: %d\n"), + static_cast(imagespec.depth)); + printf(B_TRANSLATE("descriptor: 0x%.2x\n"), + static_cast(imagespec.descriptor)); + printf(B_TRANSLATE("\talpha (attr): %d\n"), + static_cast(imagespec.descriptor & TGA_DESC_ALPHABITS)); + if (imagespec.descriptor & TGA_ORIGIN_VERT_BIT) + if (imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) + printf(B_TRANSLATE("\t origin: %d (%s %s)\n"), + static_cast(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT + | TGA_ORIGIN_HORZ_BIT)), static_cast("top"), + static_cast("right")); + else + printf(B_TRANSLATE("\t origin: %d (%s %s)\n"), + static_cast(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT + | TGA_ORIGIN_HORZ_BIT)), static_cast("top"), + static_cast("left")); + else + if (imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) + printf(B_TRANSLATE("\t origin: %d (%s %s)\n"), + static_cast(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT + | TGA_ORIGIN_HORZ_BIT)), static_cast("bottom"), + static_cast("right")); + else + printf(B_TRANSLATE("\t origin: %d (%s %s)\n"), + static_cast(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT + | TGA_ORIGIN_HORZ_BIT)), static_cast("bottom"), + static_cast("left")); + + + printf(B_TRANSLATE("\t bits 7 & 6: %d\n"), + static_cast(imagespec.descriptor & TGA_DESC_BITS76)); // Optional TGA Footer @@ -208,107 +246,128 @@ print_tga_info(BFile &file) extoffset = tga_uint32(tgafooter, 0); devoffset = tga_uint32(tgafooter, 4); - printf("\nTGA Footer:\n"); - printf("extension offset: 0x%.8lx (%ld)\n", extoffset, extoffset); - printf("developer offset: 0x%.8lx (%ld)\n", devoffset, devoffset); - printf("signature: %s\n", tgafooter + 8); + printf(B_TRANSLATE("\nTGA Footer:\n")); + printf(B_TRANSLATE("extension offset: 0x%.8lx (%ld)\n"), + static_cast(extoffset), + static_cast(extoffset)); + printf(B_TRANSLATE("developer offset: 0x%.8lx (%ld)\n"), + static_cast(devoffset), + static_cast(devoffset)); + printf(B_TRANSLATE("signature: %s\n"), tgafooter + 8); if (extoffset) { char extbuf[TGA_EXT_LEN]; if (file.ReadAt(extoffset, extbuf, TGA_EXT_LEN) == TGA_EXT_LEN) { - printf("\nExtension Area:\n"); + printf(B_TRANSLATE("\nExtension Area:\n")); char strbuffer[LINE_LEN]; uint16 extsize = tga_uint16(extbuf, 0); if (extsize < TGA_EXT_LEN) { - printf("\nError: extension area is too small (%d)\n", extsize); + printf(B_TRANSLATE("\nError: extension " + "area is too small (%d)\n"), extsize); return; } - printf("size: %d\n", extsize); + printf(B_TRANSLATE("size: %d\n"), extsize); memset(strbuffer, 0, LINE_LEN); strncpy(strbuffer, extbuf + 2, 41); printf("author: \"%s\"\n", strbuffer); - printf("comments:\n"); + printf(B_TRANSLATE("comments:\n")); for (int32 i = 0; i < 4; i++) { memset(strbuffer, 0, LINE_LEN); strcpy(strbuffer, extbuf + 43 + (i * 81)); - printf("\tline %ld: \"%s\"\n", i + 1, strbuffer); + printf(B_TRANSLATE("\tline %ld: \"%s\"\n"), + static_cast(i + 1), + static_cast(strbuffer)); } - printf("date/time (yyyy-mm-dd hh:mm:ss): %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", + printf(B_TRANSLATE("date/time (yyyy-mm-dd hh:mm:ss): " + "%.4d-%.2d-%.2d %.2d:%.2d:%.2d\n"), tga_uint16(extbuf, 367), tga_uint16(extbuf, 369), tga_uint16(extbuf, 371), tga_uint16(extbuf, 373), tga_uint16(extbuf, 375), tga_uint16(extbuf, 377)); memset(strbuffer, 0, LINE_LEN); strncpy(strbuffer, extbuf + 379, 41); - printf("job name: \"%s\"\n", strbuffer); + printf(B_TRANSLATE("job name: \"%s\"\n"), strbuffer); - printf("job time (hh:mm:ss): %.2d:%.2d:%.2d\n", - tga_uint16(extbuf, 420), tga_uint16(extbuf, 422), - tga_uint16(extbuf, 424)); + printf(B_TRANSLATE("job time (hh:mm:ss): " + "%.2d:%.2d:%.2d\n"), tga_uint16(extbuf, 420), + tga_uint16(extbuf, 422), tga_uint16(extbuf, 424)); memset(strbuffer, 0, LINE_LEN); strncpy(strbuffer, extbuf + 426, 41); - printf("software id: \"%s\"\n", strbuffer); + printf(B_TRANSLATE("software id: \"%s\"\n"), + strbuffer); char strver[] = "[null]"; if (extbuf[469] != '\0') { strver[0] = extbuf[469]; strver[1] = '\0'; } - printf("software version, letter: %d, %s\n", - tga_uint16(extbuf, 467), strver); + printf(B_TRANSLATE("software version, letter: %d, " + "%s\n"), tga_uint16(extbuf, 467), strver); - printf("key color (A,R,G,B): %d, %d, %d, %d\n", - extbuf[470], extbuf[471], extbuf[472], extbuf[473]); + printf(B_TRANSLATE("key color (A,R,G,B): %d, %d, %d, " + "%d\n"), extbuf[470], extbuf[471], extbuf[472], + extbuf[473]); - printf("pixel aspect ratio: %d / %d\n", + printf(B_TRANSLATE("pixel aspect ratio: %d / %d\n"), tga_uint16(extbuf, 474), tga_uint16(extbuf, 476)); - printf("gamma value: %d / %d\n", + printf(B_TRANSLATE("gamma value: %d / %d\n"), tga_uint16(extbuf, 478), tga_uint16(extbuf, 480)); - printf("color correction offset: 0x%.8lx (%ld)\n", - tga_uint32(extbuf, 482), tga_uint32(extbuf, 482)); - printf("postage stamp offset: 0x%.8lx (%ld)\n", - tga_uint32(extbuf, 486), tga_uint32(extbuf, 486)); - printf("scan line offset: 0x%.8lx (%ld)\n", - tga_uint32(extbuf, 490), tga_uint32(extbuf, 490)); + printf(B_TRANSLATE("color correction offset: 0x%.8lx " + "(%ld)\n"), tga_uint32(extbuf, 482), + tga_uint32(extbuf, 482)); + printf(B_TRANSLATE("postage stamp offset: 0x%.8lx " + "(%ld)\n"), tga_uint32(extbuf, 486), + tga_uint32(extbuf, 486)); + printf(B_TRANSLATE("scan line offset: 0x%.8lx " + "(%ld)\n"), tga_uint32(extbuf, 490), + tga_uint32(extbuf, 490)); const char *strattrtype = NULL; uint8 attrtype = extbuf[494]; switch (attrtype) { - case 0: strattrtype = "no alpha"; break; - case 1: strattrtype = "undefined, ignore"; break; - case 2: strattrtype = "undefined, retain"; break; - case 3: strattrtype = "alpha"; break; - case 4: strattrtype = "pre-multiplied alpha"; break; + case 0: strattrtype + = B_TRANSLATE("no alpha"); break; + case 1: strattrtype + = B_TRANSLATE("undefined, ignore"); break; + case 2: strattrtype + = B_TRANSLATE("undefined, retain"); break; + case 3: strattrtype + = B_TRANSLATE("alpha"); break; + case 4: strattrtype + = B_TRANSLATE("pre-multiplied alpha"); break; default: if (attrtype > 4 && attrtype < 128) - strattrtype = "reserved"; + strattrtype = B_TRANSLATE("reserved"); else - strattrtype = "unassigned"; + strattrtype = B_TRANSLATE("unassigned"); break; } - printf("attributes type: %d (%s)\n", attrtype, strattrtype); + printf(B_TRANSLATE("attributes type: %d (%s)\n"), + attrtype, strattrtype); } else - printf("\nError: Unable to read entire extension area\n"); + printf(B_TRANSLATE("\nError: Unable to read entire " + "extension area\n")); } } else - printf("\nTGA footer not found\n"); + printf(B_TRANSLATE("\nTGA footer not found\n")); } else - printf("\nError: Unable to read TGA footer section\n"); + printf(B_TRANSLATE("\nError: Unable to read TGA footer " + "section\n")); } else - printf("\nError: Unable to get file size\n"); + printf(B_TRANSLATE("\nError: Unable to get file size\n")); } int @@ -317,18 +376,18 @@ main(int argc, char **argv) printf("\n"); if (argc == 1) { - printf("tgainfo - reports information about a TGA image file\n"); - printf("\nUsage:\n"); - printf("tgainfo filename.tga\n"); + printf(B_TRANSLATE("tgainfo - reports information about a TGA image file\n")); + printf(B_TRANSLATE("\nUsage:\n")); + printf(B_TRANSLATE("tgainfo filename.tga\n")); } else { BFile file; for (int32 i = 1; i < argc; i++) { if (file.SetTo(argv[i], B_READ_ONLY) != B_OK) - printf("\nError opening %s\n", argv[i]); + printf(B_TRANSLATE("\nError opening %s\n"), argv[i]); else { - printf("\nTGA image information for: %s\n", argv[i]); + printf(B_TRANSLATE("\nTGA image information for: %s\n"), argv[i]); print_tga_info(file); } } diff --git a/src/tools/translation/tgainfo/tgainfo.rdef b/src/tools/translation/tgainfo/tgainfo.rdef new file mode 100644 index 0000000000..3e0810f676 --- /dev/null +++ b/src/tools/translation/tgainfo/tgainfo.rdef @@ -0,0 +1,17 @@ +/* + * tgainfo.rdef + */ + +resource app_signature "application/x-vnd.Haiku-tgainfo"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "tgainfo displays text information about TGA images.", + long_info = "Haiku tgainfo is a command line tool for displaying text information about TGA images. Written by Michael Wilber, OBOS Translation Kit Team, Copyright © 2003 OpenBeOS Project." +}; + +resource app_flags B_SINGLE_LAUNCH;