Merge branch 'master' into sam460ex

This commit is contained in:
François Revol
2013-09-17 13:22:26 +02:00
100 changed files with 2874 additions and 596 deletions
+6 -6
View File
@@ -98,11 +98,11 @@ SYSTEM_NETWORK_PROTOCOLS = ipv4 tcp udp icmp unix icmp6 ipv6 ;
SYSTEM_ADD_ONS_ACCELERANTS = [ FFilterByBuildFeatures SYSTEM_ADD_ONS_ACCELERANTS = [ FFilterByBuildFeatures
x86,x86_64 @{ x86,x86_64 @{
vesa.accelerant vesa.accelerant intel_extreme.accelerant
}@ # x86,x86_64 }@ # x86,x86_64
x86 @{ x86 @{
3dfx.accelerant ati.accelerant matrox.accelerant neomagic.accelerant 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 radeon.accelerant radeon_hd.accelerant s3.accelerant
#via.accelerant vmware.accelerant #via.accelerant vmware.accelerant
}@ # x86 }@ # 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_AUDIO_OLD = ; #cmedia usb_audio ;
SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = [ FFilterByBuildFeatures SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = [ FFilterByBuildFeatures
x86,x86_64 @{ x86,x86_64 @{
vesa vesa intel_extreme
}@ # x86,x86_64 }@ # x86,x86_64
x86 @{ 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 s3 #via vmware
}@ # x86 }@ # x86
] ; ] ;
@@ -187,7 +187,7 @@ SYSTEM_ADD_ONS_DRIVERS_NET = [ FFilterByBuildFeatures
SYSTEM_ADD_ONS_DRIVERS_POWER = [ FFilterByBuildFeatures acpi_button@x86 ] ; SYSTEM_ADD_ONS_DRIVERS_POWER = [ FFilterByBuildFeatures acpi_button@x86 ] ;
SYSTEM_ADD_ONS_BUS_MANAGERS = [ FFilterByBuildFeatures SYSTEM_ADD_ONS_BUS_MANAGERS = [ FFilterByBuildFeatures
ata@ata pci ps2@x86,x86_64 isa@x86,x86_64 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 virtio random
] ; ] ;
SYSTEM_ADD_ONS_FILE_SYSTEMS = bfs btrfs cdda exfat ext2 fat iso9660 nfs nfs4 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 AddFilesToHaikuImage system add-ons kernel bus_managers
: $(SYSTEM_ADD_ONS_BUS_MANAGERS) ; : $(SYSTEM_ADD_ONS_BUS_MANAGERS) ;
AddFilesToHaikuImage system add-ons kernel busses agp_gart AddFilesToHaikuImage system add-ons kernel busses agp_gart
: <agp_gart>intel@x86 ; : <agp_gart>intel@x86,x86_64 ;
if $(HAIKU_ATA_STACK) = 1 { if $(HAIKU_ATA_STACK) = 1 {
AddFilesToHaikuImage system add-ons kernel busses ata AddFilesToHaikuImage system add-ons kernel busses ata
+1 -1
View File
@@ -20,7 +20,7 @@ additionalMakeArgs=$*
# additional flags for the binutils build. Should there ever be any other # additional flags for the binutils build. Should there ever be any other
# flags than -jN, we need to handle this differently. # 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: # force cross-build if building on Haiku:
buildhostMachine=i586-pc-haiku_buildhost buildhostMachine=i586-pc-haiku_buildhost
buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine" buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine"
+1 -1
View File
@@ -50,7 +50,7 @@ arm-*)
;; ;;
esac esac
if [ `uname -o` = 'Haiku' ]; then if [ `uname -s` = 'Haiku' ]; then
# force cross-build if building on Haiku: # force cross-build if building on Haiku:
buildhostMachine=${haikuMachine}_buildhost buildhostMachine=${haikuMachine}_buildhost
buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine" buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine"
@@ -1,4 +1,4 @@
1 finnish x-vnd.Haiku-ActivityMonitor 2739021859 1 finnish x-vnd.Haiku-ActivityMonitor 1211510241
P-faults DataSource P-viat P-faults DataSource P-viat
Media nodes DataSource Mediasolmut Media nodes DataSource Mediasolmut
Threads DataSource Säikeet Threads DataSource Säikeet
@@ -6,6 +6,7 @@ Always on top ActivityWindow Aina päällimmäisenä
Add graph ActivityWindow Lisää kuvaaja Add graph ActivityWindow Lisää kuvaaja
Teams DataSource Ryhmät Teams DataSource Ryhmät
Hide legend ActivityView Piilota merkin selitys Hide legend ActivityView Piilota merkin selitys
MiB DataSource mebitavua
Network send DataSource Verkkolähetys Network send DataSource Verkkolähetys
CPU usage (combined) DataSource Suoritinkäyttö (yhdistetty) CPU usage (combined) DataSource Suoritinkäyttö (yhdistetty)
CPU DataSource Suoritin CPU DataSource Suoritin
@@ -26,12 +27,14 @@ Update time interval: SettingsWindow Päivitä aikaväli:
TX DataSource Shorter version for Sending Läh. TX DataSource Shorter version for Sending Läh.
Quit ActivityWindow Poistu Quit ActivityWindow Poistu
Block cache memory DataSource Lohkovälimuisti Block cache memory DataSource Lohkovälimuisti
%.1f KiB/s DataSource %.1f kibitavua/s
Remove graph ActivityView Poista kuvaaja Remove graph ActivityView Poista kuvaaja
%lld sec. SettingsWindow %lld s %lld sec. SettingsWindow %lld s
%lld ms SettingsWindow %lld ms %lld ms SettingsWindow %lld ms
CPU usage DataSource Suoritinkäyttö CPU usage DataSource Suoritinkäyttö
Raw clipboard DataSource Raakadataleikepöytä Raw clipboard DataSource Raakadataleikepöytä
Sems DataSource Opastimet Sems DataSource Opastimet
%.1f MiB DataSource %.1f Mebitavua
ActivityMonitor System name Aktiviteettivalvonta ActivityMonitor System name Aktiviteettivalvonta
Running applications DataSource Suoritetaan sovelluksia Running applications DataSource Suoritetaan sovelluksia
Semaphores DataSource Opastimet Semaphores DataSource Opastimet
+3 -1
View File
@@ -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 Select All Icon-O-Matic-PathManipulator Sélectionner tout
Add Style Icon-O-Matic-AddStylesCmd Ajouter un style Add Style Icon-O-Matic-AddStylesCmd Ajouter un style
Color (#%02x%02x%02x) Style name after dropping a color Couleur (#%02x%02x%02x) Color (#%02x%02x%02x) Style name after dropping a color Couleur (#%02x%02x%02x)
@@ -67,6 +67,7 @@ Contour Transformation Contour
Perspective Transformation Perspective Perspective Transformation Perspective
Move Transformer Icon-O-Matic-MoveTransformersCmd Déplacer la Transformation Move Transformer Icon-O-Matic-MoveTransformersCmd Déplacer la Transformation
Opacity Icon-O-Matic-PropertyNames Opacité 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é Gradient type Icon-O-Matic-StyleTypes Type de dégradé
Icon-O-Matic System name Icon-O-Matic Icon-O-Matic System name Icon-O-Matic
Cancel Icon-O-Matic-Menu-Settings Annuler 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 Translation Y Icon-O-Matic-PropertyNames Translation en Y
Rotate Icon-O-Matic-TransformationBoxStates Pivoter Rotate Icon-O-Matic-TransformationBoxStates Pivoter
Remove Transformer Icon-O-Matic-RemoveTransformersCmd Supprimer une transformation 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 Add Transformer Icon-O-Matic-AddTransformersCmd Ajouter une transformation
Remove Icon-O-Matic-PathsList Enlever Remove Icon-O-Matic-PathsList Enlever
Nudge Control Point Icon-O-Matic-NudgePointsCommand Déplacer le point de contrôle Nudge Control Point Icon-O-Matic-NudgePointsCommand Déplacer le point de contrôle
+2 -1
View File
@@ -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 Partially download messages larger than ProtocolConfigView Osittain ladatut viestit suurempia kuin
Password: ProtocolConfigView Salasana: Password: ProtocolConfigView Salasana:
Remove mail from server when deleted ProtocolConfigView Poista sähköposti palvelimelta poistettaessa Remove mail from server when deleted ProtocolConfigView Poista sähköposti palvelimelta poistettaessa
KiB ProtocolConfigView kibitavua
Mail server: ProtocolConfigView Sähköpostipalvelin: Mail server: ProtocolConfigView Sähköpostipalvelin:
Select… MailKit Valitse... Select… MailKit Valitse...
Connection type: ProtocolConfigView Yhteystyyppi: Connection type: ProtocolConfigView Yhteystyyppi:
@@ -1,4 +1,4 @@
1 belarusian x-vnd.Haiku-ScreenSaver 3630119516 1 belarusian x-vnd.Haiku-ScreenSaver 232492478
Could not load screen saver ScreenSaver Не ўдалося загрузіць захавальнік экрана Could not load screen saver ScreenSaver Не ўдалося загрузіць захавальнік экрана
30 seconds ScreenSaver 30 секунд 30 seconds ScreenSaver 30 секунд
Start screensaver ScreenSaver Запусціць захавальнік Start screensaver ScreenSaver Запусціць захавальнік
@@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Кіраванне
ScreenSaver System name Захавальнік Экрана ScreenSaver System name Захавальнік Экрана
Test ScreenSaver Тэст Test ScreenSaver Тэст
General ScreenSaver Агульныя General ScreenSaver Агульныя
Fade now when mouse is here ScreenSaver Зацямняць перасунуўшы указальнік мышы сюды
Enable screensaver ScreenSaver Уключыць захавальнік Enable screensaver ScreenSaver Уключыць захавальнік
Don't fade when mouse is here ScreenSaver Не зацямняць калі указальнік мышы знаходзіцца тут
Cancel ScreenSaver Адмена Cancel ScreenSaver Адмена
Turn off screen ScreenSaver Выключыць экран Turn off screen ScreenSaver Выключыць экран
No options available ScreenSaver Ніякія опцыі недаступныя No options available ScreenSaver Ніякія опцыі недаступныя
@@ -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. Could not load screen saver ScreenSaver Bildschirmschoner konnte nicht geladen werden.
30 seconds ScreenSaver 30 Sekunden 30 seconds ScreenSaver 30 Sekunden
Start screensaver ScreenSaver Bildschirmschoner starten Start screensaver ScreenSaver Bildschirmschoner starten
@@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Stromsparfunktione
ScreenSaver System name Bildschirmschoner ScreenSaver System name Bildschirmschoner
Test ScreenSaver Test Test ScreenSaver Test
General ScreenSaver Allgemein General ScreenSaver Allgemein
Fade now when mouse is here ScreenSaver Sofort starten, wenn Maus in diesem Eck
Enable screensaver ScreenSaver Bildschirmschoner aktivieren Enable screensaver ScreenSaver Bildschirmschoner aktivieren
Don't fade when mouse is here ScreenSaver Nicht starten, wenn Maus in diesem Eck
Cancel ScreenSaver Abbrechen Cancel ScreenSaver Abbrechen
Turn off screen ScreenSaver Bildschirm ausschalten Turn off screen ScreenSaver Bildschirm ausschalten
No options available ScreenSaver Keine Optionen verfügbar No options available ScreenSaver Keine Optionen verfügbar
@@ -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 Could not load screen saver ScreenSaver Näytönsäästäjän lataus epäonnistui
30 seconds ScreenSaver 30 sekuntia 30 seconds ScreenSaver 30 sekuntia
Start screensaver ScreenSaver Käynnistä näytönsäästäjä 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 ScreenSaver System name Näytönsäästäjäasetukset
Test ScreenSaver Testaa Test ScreenSaver Testaa
General ScreenSaver Yleinen 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ä 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 Cancel ScreenSaver Peru
Turn off screen ScreenSaver Käännä näyttö pois päältä Turn off screen ScreenSaver Käännä näyttö pois päältä
No options available ScreenSaver Valitsimia ei ole käytettävissä No options available ScreenSaver Valitsimia ei ole käytettävissä
@@ -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 Could not load screen saver ScreenSaver Impossible de charger l'économiseur d'écran
30 seconds ScreenSaver 30 secondes 30 seconds ScreenSaver 30 secondes
Start screensaver ScreenSaver Démarrer l'économiseur 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 ScreenSaver System name Économiseur d'écran
Test ScreenSaver Tester Test ScreenSaver Tester
General ScreenSaver Général 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 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 Cancel ScreenSaver Annuler
Turn off screen ScreenSaver Extinction de l'écran Turn off screen ScreenSaver Extinction de l'écran
No options available ScreenSaver Aucune option disponible No options available ScreenSaver Aucune option disponible
@@ -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 Could not load screen saver ScreenSaver A képernyővédő betöltése sikertelen
30 seconds ScreenSaver 30 másodperc 30 seconds ScreenSaver 30 másodperc
Start screensaver ScreenSaver Képernyővédő indítása 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ő ScreenSaver System name Képernyővédő
Test ScreenSaver Próba Test ScreenSaver Próba
General ScreenSaver Általános 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 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 Cancel ScreenSaver Mégse
Turn off screen ScreenSaver Képernyő kikapcsolása Turn off screen ScreenSaver Képernyő kikapcsolása
No options available ScreenSaver Nincsenek elérhető beállítások No options available ScreenSaver Nincsenek elérhető beállítások
@@ -1,4 +1,4 @@
1 japanese x-vnd.Haiku-ScreenSaver 3630119516 1 japanese x-vnd.Haiku-ScreenSaver 232492478
Could not load screen saver ScreenSaver スクリーンセーバーを実行できませんでした Could not load screen saver ScreenSaver スクリーンセーバーを実行できませんでした
30 seconds ScreenSaver 30 秒 30 seconds ScreenSaver 30 秒
Start screensaver ScreenSaver スクリーンセーバーを開始 Start screensaver ScreenSaver スクリーンセーバーを開始
@@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver DPMS (Display Powe
ScreenSaver System name スクリーンセーバー ScreenSaver System name スクリーンセーバー
Test ScreenSaver テスト Test ScreenSaver テスト
General ScreenSaver 一般 General ScreenSaver 一般
Fade now when mouse is here ScreenSaver マウスが指定の場所にあるときに画面を消す
Enable screensaver ScreenSaver スクリーンセーバーを有効にする Enable screensaver ScreenSaver スクリーンセーバーを有効にする
Don't fade when mouse is here ScreenSaver マウスが指定の場所にあるとき画面を消さない
Cancel ScreenSaver 取り消し Cancel ScreenSaver 取り消し
Turn off screen ScreenSaver 画面を消す Turn off screen ScreenSaver 画面を消す
No options available ScreenSaver 設定がありません No options available ScreenSaver 設定がありません
+5
View File
@@ -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 ;) * Figure out how to get page flags (modified/accessed) and implement it ;)
use unmapped/read-only mappings to trigger soft faults use unmapped/read-only mappings to trigger soft faults
for tracking used/modified flags for ARMv5 and ARMv6 for tracking used/modified flags for ARMv5 and ARMv6
+1 -1
View File
@@ -43,7 +43,7 @@
#define PATH_MAX (1024) #define PATH_MAX (1024)
#define PIPE_MAX (512) #define PIPE_MAX (512)
#define PTHREAD_KEYS_MAX 256 #define PTHREAD_KEYS_MAX 256
#define PTHREAD_STACK_MIN 4096 #define PTHREAD_STACK_MIN (2 * PAGE_SIZE)
#define SSIZE_MAX __HAIKU_SADDR_MAX #define SSIZE_MAX __HAIKU_SADDR_MAX
#define TTY_NAME_MAX (256) #define TTY_NAME_MAX (256)
#define TZNAME_MAX (32) #define TZNAME_MAX (32)
+1
View File
@@ -31,6 +31,7 @@
#define IFM_100_TX 6 /* 100Base-TX - RJ45 */ #define IFM_100_TX 6 /* 100Base-TX - RJ45 */
#define IFM_1000_T 16 /* 1000Base-T - RJ45 */ #define IFM_1000_T 16 /* 1000Base-T - RJ45 */
#define IFM_1000_SX 18 /* 1000Base-SX - Fiber Optic */ #define IFM_1000_SX 18 /* 1000Base-SX - Fiber Optic */
#define IFM_10G_T 22 /* 10GBase-T - RJ45 */
/* General options */ /* General options */
@@ -135,6 +135,8 @@ public:
bool IsExpanded() const; bool IsExpanded() const;
bool IsSelected() const; bool IsSelected() const;
void Invalidate();
private: private:
// Blows up into the debugger if the validation fails. // Blows up into the debugger if the validation fails.
void ValidateFields() const; void ValidateFields() const;
@@ -332,6 +334,8 @@ public:
parentRow1 = NULL, BRow* parentRow2 = NULL); parentRow1 = NULL, BRow* parentRow2 = NULL);
void Clear(); void Clear();
void InvalidateRow(BRow* row);
// Appearance (DEPRECATED) // Appearance (DEPRECATED)
void GetFont(BFont* font) const void GetFont(BFont* font) const
{ BView::GetFont(font); } { BView::GetFont(font); }
+4 -4
View File
@@ -13,10 +13,10 @@
/** Size of the stack given to teams in user space */ /** Size of the stack given to teams in user space */
#define USER_STACK_GUARD_SIZE (4 * B_PAGE_SIZE) // 16 kB #define USER_STACK_GUARD_SIZE (4 * B_PAGE_SIZE) // 16 kB
#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB #define MIN_USER_STACK_SIZE (2 * B_PAGE_SIZE) // 8 kB
#define USER_STACK_SIZE (256 * 1024) // 256 kB #define MAX_USER_STACK_SIZE (4096 * B_PAGE_SIZE) // 16 MB
#define MIN_USER_STACK_SIZE (8 * 1024) // 8 kB #define USER_MAIN_THREAD_STACK_SIZE MAX_USER_STACK_SIZE
#define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB #define USER_STACK_SIZE (64 * B_PAGE_SIZE) // 256 kB
// The type of object a thread blocks on (thread::wait::type, set by // The type of object a thread blocks on (thread::wait::type, set by
@@ -141,9 +141,11 @@ init_common(int device, bool isClone)
// The overlay registers, hardware status, and cursor memory share // The overlay registers, hardware status, and cursor memory share
// a single area with the shared_info // a single area with the shared_info
gInfo->overlay_registers = (struct overlay_registers*) if (gInfo->shared_info->overlay_offset != 0) {
(gInfo->shared_info->graphics_memory gInfo->overlay_registers = (struct overlay_registers*)
+ gInfo->shared_info->overlay_offset); (gInfo->shared_info->graphics_memory
+ gInfo->shared_info->overlay_offset);
}
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_96x)) { if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_96x)) {
// allocate some extra memory for the 3D context // allocate some extra memory for the 3D context
@@ -431,7 +431,10 @@ retrieve_current_mode(display_mode& mode, uint32 pllRegister)
mode.h_display_start = 0; mode.h_display_start = 0;
mode.v_display_start = 0; mode.v_display_start = 0;
mode.flags = B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS 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;
}
} }
@@ -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 static status_t
hda_codec_switch_handler(hda_codec* codec) 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; codec->unsol_response_read %= MAX_CODEC_UNSOL_RESPONSES;
bool disable = response & 1; bool disable = response & 1;
hda_audio_group* audioGroup = codec->audio_groups[0]; hda_codec_check_sense(codec, disable);
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);
}
} }
return B_OK; 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( codec->unsol_response_thread = spawn_kernel_thread(
(status_t(*)(void*))hda_codec_switch_handler, (status_t(*)(void*))hda_codec_switch_handler,
"hda_codec_unsol_thread", B_LOW_PRIORITY, codec); "hda_codec_unsol_thread", B_LOW_PRIORITY, codec);
@@ -31,7 +31,10 @@
#define NORFLASH_ADDR 0x00000000 #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 { struct nor_driver_info {
device_node *node; device_node *node;
@@ -54,7 +57,7 @@ nor_init_device(void *_info, void **_cookie)
info->mapped = NULL; info->mapped = NULL;
info->blocksize = 128 * 1024; 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); info->id = map_physical_memory("NORFlash", NORFLASH_ADDR, info->totalsize, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &info->mapped);
if (info->id < 0) 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; nor_driver_info *info = (nor_driver_info*)_cookie;
TRACE("read(%Ld,%lu)\n", position, *numbytes); TRACE("read(%Ld,%lu)\n", position, *numbytes);
position += HIDDEN_BLOCKS * info->blocksize;
if (position + *numbytes > info->totalsize) if (position + *numbytes > info->totalsize)
*numbytes = info->totalsize - (position + *numbytes); *numbytes = info->totalsize - (position + *numbytes);
@@ -160,8 +165,16 @@ nor_write(void *_cookie, off_t position, const void *data, size_t *numbytes)
static float static float
nor_supports_device(device_node *parent) nor_supports_device(device_node *parent)
{ {
const char *bus;
TRACE("supports_device\n"); 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;
} }
@@ -267,8 +267,8 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength,
uint32 logicalBlockAddress, uint16 transferLength, void *data, uint32 logicalBlockAddress, uint16 transferLength, void *data,
size_t *dataLength, bool directionIn) size_t *dataLength, bool directionIn)
{ {
TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %lu; tlen: %u; data: " TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %" B_PRIu32
"%p; dlen: %p (%lu); in: %c\n", "; tlen: %u; data: %p; dlen: %p (%lu); in: %c\n",
lun->logical_unit_number, operation, opLength, logicalBlockAddress, lun->logical_unit_number, operation, opLength, logicalBlockAddress,
transferLength, data, dataLength, dataLength ? *dataLength : 0, transferLength, data, dataLength, dataLength ? *dataLength : 0,
directionIn ? 'y' : 'n'); directionIn ? 'y' : 'n');
@@ -487,7 +487,7 @@ usb_disk_request_sense(device_lun *lun)
parameter.additional_sense_code_qualifier); parameter.additional_sense_code_qualifier);
lun->media_present = false; lun->media_present = false;
usb_disk_reset_capacity(lun); usb_disk_reset_capacity(lun);
return B_DEV_NO_MEDIA; return B_DEV_NOT_READY;
case SCSI_SENSE_KEY_DATA_PROTECT: case SCSI_SENSE_KEY_DATA_PROTECT:
TRACE_ALWAYS("request_sense: write protected\n"); TRACE_ALWAYS("request_sense: write protected\n");
@@ -691,7 +691,7 @@ usb_disk_callback(void *cookie, status_t status, void *data,
static status_t static status_t
usb_disk_device_added(usb_device newDevice, void **cookie) 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)); disk_device *device = (disk_device *)malloc(sizeof(disk_device));
device->device = newDevice; device->device = newDevice;
device->removed = false; 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); sprintf(device->luns[i]->name, DEVICE_NAME, device->device_number, i);
mutex_unlock(&gDeviceListLock); mutex_unlock(&gDeviceListLock);
TRACE("new device: 0x%08lx\n", (uint32)device); TRACE("new device: 0x%p\n", device);
*cookie = (void *)device; *cookie = (void *)device;
return B_OK; return B_OK;
} }
@@ -865,7 +865,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
static status_t static status_t
usb_disk_device_removed(void *cookie) 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; disk_device *device = (disk_device *)cookie;
mutex_lock(&gDeviceListLock); mutex_lock(&gDeviceListLock);
@@ -963,7 +963,7 @@ usb_disk_prepare_partial_buffer(device_lun *lun, off_t position, size_t length,
return result; return result;
} }
off_t offset = position - (blockPosition * lun->block_size); off_t offset = position - (off_t)blockPosition * lun->block_size;
partialBuffer = (uint8 *)blockBuffer + offset; partialBuffer = (uint8 *)blockBuffer + offset;
return B_OK; return B_OK;
} }
@@ -1096,7 +1096,8 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
case B_GET_MEDIA_STATUS: case B_GET_MEDIA_STATUS:
{ {
*(status_t *)buffer = usb_disk_test_unit_ready(lun); *(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; result = B_OK;
break; break;
} }
@@ -1117,8 +1118,9 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
geometry.removable = lun->removable; geometry.removable = lun->removable;
geometry.read_only = lun->write_protected; geometry.read_only = lun->write_protected;
geometry.write_once = lun->device_type == B_WORM; geometry.write_once = lun->device_type == B_WORM;
TRACE("B_GET_GEOMETRY: %ld sectors at %ld bytes per sector\n", TRACE("B_GET_GEOMETRY: %" B_PRId32 " sectors at %" B_PRId32
geometry.cylinder_count, geometry.bytes_per_sector); " bytes per sector\n", geometry.cylinder_count,
geometry.bytes_per_sector);
result = user_memcpy(buffer, &geometry, sizeof(device_geometry)); result = user_memcpy(buffer, &geometry, sizeof(device_geometry));
break; break;
} }
@@ -1212,7 +1214,7 @@ usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length)
if (buffer == NULL || length == NULL) if (buffer == NULL || length == NULL)
return B_BAD_VALUE; 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; device_lun *lun = (device_lun *)cookie;
disk_device *device = lun->device; disk_device *device = lun->device;
mutex_lock(&device->lock); mutex_lock(&device->lock);
@@ -1260,7 +1262,7 @@ usb_disk_write(void *cookie, off_t position, const void *buffer,
if (buffer == NULL || length == NULL) if (buffer == NULL || length == NULL)
return B_BAD_VALUE; 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; device_lun *lun = (device_lun *)cookie;
disk_device *device = lun->device; disk_device *device = lun->device;
mutex_lock(&device->lock); mutex_lock(&device->lock);
@@ -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_davicom ;
SubInclude HAIKU_TOP src add-ons kernel drivers network usb_ecm ; 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 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 vlance ;
SubInclude HAIKU_TOP src add-ons kernel drivers network wb840 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wb840 ;
@@ -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
;
@@ -0,0 +1,462 @@
/*
* Copyright 2013, Jérôme Duval, korli@users.berlios.de.
* Distributed under the terms of the MIT License.
*/
#include <ethernet.h>
#include <virtio.h>
#include <net/if_media.h>
#include <new>
#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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fs/devfs.h>
#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
};
@@ -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 */
@@ -633,7 +633,8 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
inode->SetAccessTime(&timespec); inode->SetAccessTime(&timespec);
inode->SetCreationTime(&timespec); inode->SetCreationTime(&timespec);
inode->SetModificationTime(&timespec); inode->SetModificationTime(&timespec);
node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED); if (parent != NULL)
node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED);
if (volume->HasExtentsFeature() if (volume->HasExtentsFeature()
&& (inode->IsDirectory() || inode->IsFile())) { && (inode->IsDirectory() || inode->IsFile())) {
node.SetFlag(EXT2_INODE_EXTENTS); node.SetFlag(EXT2_INODE_EXTENTS);
@@ -935,4 +936,3 @@ Inode::IncrementNumLinks(Transaction& transaction)
fVolume->ActivateDirNLink(transaction); fVolume->ActivateDirNLink(transaction);
} }
} }
@@ -654,6 +654,10 @@ struct ext2_inode {
#define EXT2_INODE_DIR_SYNCH 0x00010000 #define EXT2_INODE_DIR_SYNCH 0x00010000
#define EXT2_INODE_HUGE_FILE 0x00040000 #define EXT2_INODE_HUGE_FILE 0x00040000
#define EXT2_INODE_EXTENTS 0x00080000 #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 \ #define EXT2_INODE_INHERITED (EXT2_INODE_SECURE_DELETION | EXT2_INODE_UNDELETE \
| EXT2_INODE_COMPRESSED | EXT2_INODE_SYNCHRONOUS | EXT2_INODE_IMMUTABLE \ | EXT2_INODE_COMPRESSED | EXT2_INODE_SYNCHRONOUS | EXT2_INODE_IMMUTABLE \
@@ -274,7 +274,9 @@ fs_identify_partition(int fd, partition_data *partition, void **_cookie)
*_cookie = 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;
} }
+4 -4
View File
@@ -64,7 +64,7 @@ dpc_thread(void *arg)
} }
// Let's finish the pending DPCs, if any. // Let's finish the pending DPCs, if any.
// Otherwise, resource could leaks... // Otherwise, resource could leak...
while (queue->count--) { while (queue->count--) {
dpc = queue->slots[queue->head]; dpc = queue->slots[queue->head];
queue->head = (queue->head + 1) % queue->size; queue->head = (queue->head + 1) % queue->size;
@@ -135,7 +135,7 @@ delete_dpc_queue(void *handle)
if (!queue) if (!queue)
return B_BAD_VALUE; 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(); former = disable_interrupts();
acquire_spinlock(&queue->lock); acquire_spinlock(&queue->lock);
@@ -186,8 +186,8 @@ queue_dpc(void *handle, dpc_func function, void *arg)
restore_interrupts(former); restore_interrupts(former);
if (status == B_OK) if (status == B_OK)
// Wake up the corresponding dpc thead // Wake up the corresponding dpc thread
// Notice that interrupt handlers should returns B_INVOKE_SCHEDULER to // Notice that interrupt handlers should return B_INVOKE_SCHEDULER to
// shorten DPC latency as much as possible... // shorten DPC latency as much as possible...
status = release_sem_etc(queue->wakeup_sem, 1, B_DO_NOT_RESCHEDULE); status = release_sem_etc(queue->wakeup_sem, 1, B_DO_NOT_RESCHEDULE);
-3
View File
@@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui.o MergeObject DebugAnalyzer_gui.o
: :
AbstractGeneralPage.cpp AbstractGeneralPage.cpp
-3
View File
@@ -4,9 +4,6 @@ UsePrivateHeaders shared ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui_chart.o MergeObject DebugAnalyzer_gui_chart.o
: :
BigtimeChartAxisLegendSource.cpp BigtimeChartAxisLegendSource.cpp
@@ -7,9 +7,6 @@ UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
UseHeaders [ FDirName $(HAIKU_TOP) src apps debugger util ] ; UseHeaders [ FDirName $(HAIKU_TOP) src apps debugger util ] ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui_main_window.o MergeObject DebugAnalyzer_gui_main_window.o
: :
GeneralPage.cpp GeneralPage.cpp
-3
View File
@@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui_table.o MergeObject DebugAnalyzer_gui_table.o
: :
AbstractTable.cpp AbstractTable.cpp
@@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui_thread_window.o MergeObject DebugAnalyzer_gui_thread_window.o
: :
ActivityPage.cpp ActivityPage.cpp
-3
View File
@@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_model.o MergeObject DebugAnalyzer_model.o
: :
Model.cpp Model.cpp
@@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_model_loader.o MergeObject DebugAnalyzer_model_loader.o
: :
AbstractModelLoader.cpp AbstractModelLoader.cpp
-3
View File
@@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_util.o MergeObject DebugAnalyzer_util.o
: :
DataSource.cpp DataSource.cpp
+1 -3
View File
@@ -1,8 +1,5 @@
SubDir HAIKU_TOP src apps debugger ; SubDir HAIKU_TOP src apps debugger ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
# for syscall_numbers.h # for syscall_numbers.h
@@ -184,6 +181,7 @@ Application Debugger :
BreakpointSetting.cpp BreakpointSetting.cpp
GuiTeamUiSettings.cpp GuiTeamUiSettings.cpp
SettingsManager.cpp SettingsManager.cpp
TeamFileManagerSettings.cpp
TeamSettings.cpp TeamSettings.cpp
TeamUiSettings.cpp TeamUiSettings.cpp
TeamUiSettingsFactory.cpp TeamUiSettingsFactory.cpp
@@ -1,8 +1,5 @@
SubDir HAIKU_TOP src apps debugger arch x86 disasm ; SubDir HAIKU_TOP src apps debugger arch x86 disasm ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
UsePrivateHeaders shared ; UsePrivateHeaders shared ;
UseHeaders [ LibraryHeaders udis86 ] ; UseHeaders [ LibraryHeaders udis86 ] ;
@@ -315,8 +315,8 @@ ArchitectureX8664::CreateStackFrame(Image* image, FunctionDebugInfo* function,
// The syscall stubs are frameless, the return address is on top of the // The syscall stubs are frameless, the return address is on top of the
// stack. // stack.
uint32 rsp = cpuState->IntRegisterValue(X86_64_REGISTER_RSP); uint64 rsp = cpuState->IntRegisterValue(X86_64_REGISTER_RSP);
uint32 address; uint64 address;
if (fTeamMemory->ReadMemory(rsp, &address, 8) == 8) { if (fTeamMemory->ReadMemory(rsp, &address, 8) == 8) {
returnAddress = address; returnAddress = address;
previousFramePointer = framePointer; previousFramePointer = framePointer;
@@ -1,8 +1,5 @@
SubDir HAIKU_TOP src apps debugger arch x86_64 disasm ; SubDir HAIKU_TOP src apps debugger arch x86_64 disasm ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
UsePrivateHeaders shared ; UsePrivateHeaders shared ;
UseHeaders [ LibraryHeaders udis86 ] ; UseHeaders [ LibraryHeaders udis86 ] ;
@@ -18,12 +18,15 @@
#include "AreaInfo.h" #include "AreaInfo.h"
#include "CpuState.h" #include "CpuState.h"
#include "DebuggerInterface.h" #include "DebuggerInterface.h"
#include "DisassembledCode.h"
#include "FunctionInstance.h"
#include "Image.h" #include "Image.h"
#include "MessageCodes.h" #include "MessageCodes.h"
#include "Register.h" #include "Register.h"
#include "SemaphoreInfo.h" #include "SemaphoreInfo.h"
#include "StackFrame.h" #include "StackFrame.h"
#include "StackTrace.h" #include "StackTrace.h"
#include "Statement.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "SystemInfo.h" #include "SystemInfo.h"
#include "Team.h" #include "Team.h"
@@ -51,7 +54,8 @@ DebugReportGenerator::DebugReportGenerator(::Team* team,
fWaitingNode(NULL), fWaitingNode(NULL),
fCurrentBlock(NULL), fCurrentBlock(NULL),
fBlockRetrievalStatus(B_OK), fBlockRetrievalStatus(B_OK),
fTraceWaitingThread(NULL) fTraceWaitingThread(NULL),
fSourceWaitingFunction(NULL)
{ {
fTeam->AddListener(this); fTeam->AddListener(this);
fArchitecture->AcquireReference(); 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 status_t
DebugReportGenerator::_GenerateReportHeader(BString& _output) DebugReportGenerator::_GenerateReportHeader(BString& _output)
{ {
@@ -452,9 +470,12 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output,
&& frame->CountLocalVariables() == 0) { && frame->CountLocalVariables() == 0) {
// only dump the topmost frame // only dump the topmost frame
if (i == 0) { if (i == 0) {
locker.Unlock();
_DumpFunctionDisassembly(_output, frame->InstructionPointer());
_DumpStackFrameMemory(_output, thread->GetCpuState(), _DumpStackFrameMemory(_output, thread->GetCpuState(),
frame->FrameAddress(), thread->GetTeam()->GetArchitecture() frame->FrameAddress(), thread->GetTeam()->GetArchitecture()
->StackGrowthDirection()); ->StackGrowthDirection());
locker.Lock();
} }
continue; 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 void
DebugReportGenerator::_DumpStackFrameMemory(BString& _output, DebugReportGenerator::_DumpStackFrameMemory(BString& _output,
CpuState* state, target_addr_t framePointer, uint8 stackDirection) CpuState* state, target_addr_t framePointer, uint8 stackDirection)
@@ -519,11 +600,11 @@ DebugReportGenerator::_DumpStackFrameMemory(BString& _output,
_output << "\t\t\tFrame memory:\n"; _output << "\t\t\tFrame memory:\n";
if (fBlockRetrievalStatus == B_OK) { if (fBlockRetrievalStatus == B_OK) {
UiUtils::DumpMemory(_output, 3, fCurrentBlock, startAddress, 1, 16, UiUtils::DumpMemory(_output, 4 , fCurrentBlock, startAddress, 1, 16,
endAddress - startAddress); endAddress - startAddress);
} else { } else {
BString data; BString data;
data.SetToFormat("\t\t\tUnavailable (%s)\n", strerror( data.SetToFormat("\t\t\t\tUnavailable (%s)\n", strerror(
fBlockRetrievalStatus)); fBlockRetrievalStatus));
_output += data; _output += data;
} }
@@ -8,6 +8,7 @@
#include <Looper.h> #include <Looper.h>
#include "Function.h"
#include "Team.h" #include "Team.h"
#include "TeamMemoryBlock.h" #include "TeamMemoryBlock.h"
#include "ValueNodeContainer.h" #include "ValueNodeContainer.h"
@@ -30,7 +31,8 @@ class ValueNodeManager;
class DebugReportGenerator : public BLooper, private Team::Listener, class DebugReportGenerator : public BLooper, private Team::Listener,
private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener { private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener,
private Function::Listener {
public: public:
DebugReportGenerator(::Team* team, DebugReportGenerator(::Team* team,
UserInterfaceListener* listener, UserInterfaceListener* listener,
@@ -58,6 +60,8 @@ private:
// ValueNodeContainer::Listener // ValueNodeContainer::Listener
virtual void ValueNodeValueChanged(ValueNode* node); virtual void ValueNodeValueChanged(ValueNode* node);
// Function::Listener
virtual void FunctionSourceCodeChanged(Function* function);
private: private:
status_t _GenerateReport(const entry_ref& outputPath); status_t _GenerateReport(const entry_ref& outputPath);
@@ -68,6 +72,8 @@ private:
status_t _DumpRunningThreads(BString& _output); status_t _DumpRunningThreads(BString& _output);
status_t _DumpDebuggedThreadInfo(BString& _output, status_t _DumpDebuggedThreadInfo(BString& _output,
::Thread* thread); ::Thread* thread);
void _DumpFunctionDisassembly(BString& _output,
target_addr_t instructionPointer);
void _DumpStackFrameMemory(BString& _output, void _DumpStackFrameMemory(BString& _output,
CpuState* state, CpuState* state,
target_addr_t framePointer, target_addr_t framePointer,
@@ -97,6 +103,7 @@ private:
TeamMemoryBlock* fCurrentBlock; TeamMemoryBlock* fCurrentBlock;
status_t fBlockRetrievalStatus; status_t fBlockRetrievalStatus;
::Thread* fTraceWaitingThread; ::Thread* fTraceWaitingThread;
Function* fSourceWaitingFunction;
}; };
#endif // DEBUG_REPORT_GENERATOR_H #endif // DEBUG_REPORT_GENERATOR_H
@@ -1991,6 +1991,8 @@ TeamDebugger::_LoadSettings()
breakpointSetting->IsEnabled()); breakpointSetting->IsEnabled());
} }
fFileManager->LoadLocationMappings(fTeamSettings.FileManagerSettings());
const TeamUiSettings* uiSettings = fTeamSettings.UiSettingFor( const TeamUiSettings* uiSettings = fTeamSettings.UiSettingFor(
fUserInterface->ID()); fUserInterface->ID());
if (uiSettings != NULL) if (uiSettings != NULL)
@@ -2022,6 +2024,8 @@ TeamDebugger::_SaveSettings()
settings.AddUiSettings(clonedSettings); settings.AddUiSettings(clonedSettings);
} }
} }
fFileManager->SaveLocationMappings(settings.FileManagerSettings());
locker.Unlock(); locker.Unlock();
// save the settings // save the settings
-3
View File
@@ -1,8 +1,5 @@
SubDir HAIKU_TOP src apps debugger demangler ; SubDir HAIKU_TOP src apps debugger demangler ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
SEARCH_SOURCE SEARCH_SOURCE
+= [ FDirName $(HAIKU_TOP) src add-ons kernel debugger demangle ] ; += [ FDirName $(HAIKU_TOP) src add-ons kernel debugger demangle ] ;
-3
View File
@@ -1,8 +1,5 @@
SubDir HAIKU_TOP src apps debugger dwarf ; SubDir HAIKU_TOP src apps debugger dwarf ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
UsePrivateHeaders kernel shared ; UsePrivateHeaders kernel shared ;
UsePrivateSystemHeaders ; UsePrivateSystemHeaders ;
+80 -6
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * 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. * Distributed under the terms of the MIT License.
*/ */
@@ -15,6 +15,7 @@
#include "LocatableFile.h" #include "LocatableFile.h"
#include "SourceFile.h" #include "SourceFile.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "TeamFileManagerSettings.h"
// #pragma mark - EntryPath // #pragma mark - EntryPath
@@ -611,7 +612,8 @@ FileManager::GetTargetFile(const BString& path)
void void
FileManager::TargetEntryLocated(const BString& path, const BString& locatedPath) FileManager::TargetEntryLocated(const BString& path,
const BString& locatedPath)
{ {
AutoLocker<FileManager> locker(this); AutoLocker<FileManager> locker(this);
fTargetDomain->EntryLocated(path, locatedPath); fTargetDomain->EntryLocated(path, locatedPath);
@@ -623,7 +625,14 @@ FileManager::GetSourceFile(const BString& directory,
const BString& relativePath) const BString& relativePath)
{ {
AutoLocker<FileManager> locker(this); AutoLocker<FileManager> 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) FileManager::GetSourceFile(const BString& path)
{ {
AutoLocker<FileManager> locker(this); AutoLocker<FileManager> locker(this);
return fSourceDomain->GetFile(path); LocatableFile* file = fSourceDomain->GetFile(path);
_LocateFileIfMapped(path, file);
return file;
} }
void status_t
FileManager::SourceEntryLocated(const BString& path, const BString& locatedPath) FileManager::SourceEntryLocated(const BString& path,
const BString& locatedPath)
{ {
AutoLocker<FileManager> locker(this); AutoLocker<FileManager> locker(this);
fSourceDomain->EntryLocated(path, locatedPath); 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<FileManager> 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<FileManager> 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::SourceFileEntry*
FileManager::_LookupSourceFile(const BString& path) FileManager::_LookupSourceFile(const BString& path)
{ {
@@ -713,3 +773,17 @@ FileManager::_SourceFileUnused(SourceFileEntry* entry)
if (otherEntry == entry) if (otherEntry == entry)
fSourceFiles->Remove(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);
}
}
+16 -1
View File
@@ -1,11 +1,15 @@
/* /*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef FILE_MANAGER_H #ifndef FILE_MANAGER_H
#define FILE_MANAGER_H #define FILE_MANAGER_H
#include <map>
#include <Locker.h> #include <Locker.h>
#include <Message.h>
#include <String.h> #include <String.h>
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
@@ -15,6 +19,7 @@
class LocatableEntry; class LocatableEntry;
class LocatableFile; class LocatableFile;
class SourceFile; class SourceFile;
class TeamFileManagerSettings;
class FileManager { class FileManager {
@@ -40,13 +45,18 @@ public:
// returns a reference // returns a reference
LocatableFile* GetSourceFile(const BString& path); LocatableFile* GetSourceFile(const BString& path);
// returns a reference // returns a reference
void SourceEntryLocated(const BString& path, status_t SourceEntryLocated(const BString& path,
const BString& locatedPath); const BString& locatedPath);
status_t LoadSourceFile(LocatableFile* file, status_t LoadSourceFile(LocatableFile* file,
SourceFile*& _sourceFile); SourceFile*& _sourceFile);
// returns a reference // returns a reference
status_t LoadLocationMappings(TeamFileManagerSettings*
settings);
status_t SaveLocationMappings(TeamFileManagerSettings*
settings);
private: private:
struct EntryPath; struct EntryPath;
struct EntryHashDefinition; struct EntryHashDefinition;
@@ -57,6 +67,7 @@ private:
typedef BOpenHashTable<EntryHashDefinition> LocatableEntryTable; typedef BOpenHashTable<EntryHashDefinition> LocatableEntryTable;
typedef DoublyLinkedList<LocatableEntry> DeadEntryList; typedef DoublyLinkedList<LocatableEntry> DeadEntryList;
typedef BOpenHashTable<SourceFileHashDefinition> SourceFileTable; typedef BOpenHashTable<SourceFileHashDefinition> SourceFileTable;
typedef std::map<BString, BString> LocatedFileMap;
friend struct SourceFileEntry; friend struct SourceFileEntry;
// for gcc 2 // for gcc 2
@@ -64,12 +75,16 @@ private:
private: private:
SourceFileEntry* _LookupSourceFile(const BString& path); SourceFileEntry* _LookupSourceFile(const BString& path);
void _SourceFileUnused(SourceFileEntry* entry); void _SourceFileUnused(SourceFileEntry* entry);
void _LocateFileIfMapped(const BString& sourcePath,
LocatableFile* file);
private: private:
BLocker fLock; BLocker fLock;
Domain* fTargetDomain; Domain* fTargetDomain;
Domain* fSourceDomain; Domain* fSourceDomain;
SourceFileTable* fSourceFiles; SourceFileTable* fSourceFiles;
LocatedFileMap fSourceLocationMappings;
}; };
@@ -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;
}
@@ -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 <Message.h>
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
@@ -16,6 +16,7 @@
#include "ArchivingUtils.h" #include "ArchivingUtils.h"
#include "BreakpointSetting.h" #include "BreakpointSetting.h"
#include "Team.h" #include "Team.h"
#include "TeamFileManagerSettings.h"
#include "TeamUiSettings.h" #include "TeamUiSettings.h"
#include "TeamUiSettingsFactory.h" #include "TeamUiSettingsFactory.h"
#include "UserBreakpoint.h" #include "UserBreakpoint.h"
@@ -23,6 +24,7 @@
TeamSettings::TeamSettings() 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; return B_OK;
} }
@@ -149,6 +157,14 @@ TeamSettings::WriteTo(BMessage& archive) const
return error; 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; return B_OK;
} }
@@ -234,10 +250,32 @@ TeamSettings::operator=(const TeamSettings& other)
} }
} }
*fFileManagerSettings = *other.fFileManagerSettings;
return *this; 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 void
TeamSettings::_Unset() TeamSettings::_Unset()
{ {
@@ -1,5 +1,6 @@
/* /*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef TEAM_SETTINGS_H #ifndef TEAM_SETTINGS_H
@@ -15,6 +16,7 @@ class BMessage;
class Team; class Team;
class BreakpointSetting; class BreakpointSetting;
class TeamUiSettings; class TeamUiSettings;
class TeamFileManagerSettings;
class TeamSettings { class TeamSettings {
@@ -41,6 +43,11 @@ public:
TeamSettings& operator=(const TeamSettings& other); TeamSettings& operator=(const TeamSettings& other);
// throws std::bad_alloc // throws std::bad_alloc
TeamFileManagerSettings*
FileManagerSettings() const;
status_t SetFileManagerSettings(
TeamFileManagerSettings* settings);
private: private:
typedef BObjectList<BreakpointSetting> BreakpointList; typedef BObjectList<BreakpointSetting> BreakpointList;
typedef BObjectList<TeamUiSettings> UiSettingsList; typedef BObjectList<TeamUiSettings> UiSettingsList;
@@ -51,6 +58,8 @@ private:
private: private:
BreakpointList fBreakpoints; BreakpointList fBreakpoints;
UiSettingsList fUiSettings; UiSettingsList fUiSettings;
TeamFileManagerSettings*
fFileManagerSettings;
BString fTeamName; BString fTeamName;
}; };
@@ -11,20 +11,30 @@
#include <stdio.h> #include <stdio.h>
#include <ByteOrder.h> #include <ByteOrder.h>
#include <Clipboard.h>
#include <Looper.h> #include <Looper.h>
#include <MenuItem.h>
#include <MessageRunner.h>
#include <Messenger.h> #include <Messenger.h>
#include <PopUpMenu.h>
#include <Region.h>
#include <ScrollView.h> #include <ScrollView.h>
#include <String.h> #include <String.h>
#include "Architecture.h" #include "Architecture.h"
#include "AutoDeleter.h"
#include "MessageCodes.h"
#include "Team.h" #include "Team.h"
#include "TeamMemoryBlock.h" #include "TeamMemoryBlock.h"
enum { 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) MemoryView::MemoryView(::Team* team, Listener* listener)
: :
@@ -39,6 +49,10 @@ MemoryView::MemoryView(::Team* team, Listener* listener)
fHexBlocksPerLine(0), fHexBlocksPerLine(0),
fHexMode(HexMode8BitInt), fHexMode(HexMode8BitInt),
fTextMode(TextModeASCII), fTextMode(TextModeASCII),
fSelectionBase(0),
fSelectionStart(0),
fSelectionEnd(0),
fScrollRunner(NULL),
fListener(listener) fListener(listener)
{ {
Architecture* architecture = team->GetArchitecture(); Architecture* architecture = team->GetArchitecture();
@@ -76,11 +90,14 @@ void
MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address) MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address)
{ {
fTargetAddress = address; fTargetAddress = address;
if (fTargetBlock != NULL) if (block != fTargetBlock && fTargetBlock != NULL)
fTargetBlock->ReleaseReference(); fTargetBlock->ReleaseReference();
fTargetBlock = block; if (block != fTargetBlock) {
fTargetBlock->AcquireReference(); fTargetBlock = block;
fTargetBlock->AcquireReference();
}
MakeFocus(true); MakeFocus(true);
BMessenger(this).SendMessage(MSG_TARGET_ADDRESS_CHANGED); BMessenger(this).SendMessage(MSG_TARGET_ADDRESS_CHANGED);
} }
@@ -119,7 +136,7 @@ MemoryView::Draw(BRect rect)
if (fTargetBlock == NULL) if (fTargetBlock == NULL)
return; return;
uint32 hexBlockSize = (1 << fHexMode) + 1; uint32 hexBlockSize = _GetHexDigitsPerBlock() + 1;
uint32 blockByteSize = hexBlockSize / 2; uint32 blockByteSize = hexBlockSize / 2;
if (fHexMode != HexModeNone && fTextMode != TextModeNone) { if (fHexMode != HexModeNone && fTextMode != TextModeNone) {
divider += (fHexBlocksPerLine * hexBlockSize + 1) * fCharWidth; divider += (fHexBlocksPerLine * hexBlockSize + 1) * fCharWidth;
@@ -156,7 +173,6 @@ MemoryView::Draw(BRect rect)
DrawString(buffer, drawPoint); DrawString(buffer, drawPoint);
drawPoint.x += fCharWidth * (fTargetAddressSize + 2); drawPoint.x += fCharWidth * (fTargetAddressSize + 2);
PopState(); PopState();
if (fHexMode != HexModeNone) { if (fHexMode != HexModeNone) {
if (currentAddress + (currentBlocksPerLine * blockByteSize) if (currentAddress + (currentBlocksPerLine * blockByteSize)
> maxAddress) { > maxAddress) {
@@ -168,20 +184,15 @@ MemoryView::Draw(BRect rect)
for (int32 j = 0; j < currentBlocksPerLine; j++) { for (int32 j = 0; j < currentBlocksPerLine; j++) {
const char* blockAddress = currentAddress + (j const char* blockAddress = currentAddress + (j
* blockByteSize); * blockByteSize);
_GetNextHexBlock(buffer, _GetNextHexBlock(buffer, sizeof(buffer), blockAddress);
std::min((size_t)hexBlockSize, sizeof(buffer)),
blockAddress);
DrawString(buffer, drawPoint);
if (targetAddress >= blockAddress && targetAddress < if (targetAddress >= blockAddress && targetAddress <
blockAddress + blockByteSize) { blockAddress + blockByteSize) {
PushState(); PushState();
SetHighColor(B_TRANSPARENT_COLOR); SetHighColor(make_color(216,0,0));
SetDrawingMode(B_OP_INVERT); DrawString(buffer, drawPoint);
FillRect(BRect(drawPoint.x, drawPoint.y - fh.ascent,
drawPoint.x + (hexBlockSize - 1) * fCharWidth,
drawPoint.y + fh.descent));
PopState(); PopState();
} } else
DrawString(buffer, drawPoint);
drawPoint.x += fCharWidth * hexBlockSize; drawPoint.x += fCharWidth * hexBlockSize;
} }
@@ -190,6 +201,7 @@ MemoryView::Draw(BRect rect)
drawPoint.x += fCharWidth * hexBlockSize drawPoint.x += fCharWidth * hexBlockSize
* (fHexBlocksPerLine - currentBlocksPerLine); * (fHexBlocksPerLine - currentBlocksPerLine);
} }
if (fTextMode != TextModeNone) { if (fTextMode != TextModeNone) {
drawPoint.x += fCharWidth; drawPoint.x += fCharWidth;
for (int32 j = 0; j < currentCharsPerLine; j++) { for (int32 j = 0; j < currentCharsPerLine; j++) {
@@ -226,6 +238,15 @@ MemoryView::Draw(BRect rect)
lineAddress += fTextCharsPerLine; 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) MemoryView::MessageReceived(BMessage* message)
{ {
switch(message->what) { switch(message->what) {
case B_COPY:
{
_CopySelectionToClipboard();
break;
}
case MSG_TARGET_ADDRESS_CHANGED: case MSG_TARGET_ADDRESS_CHANGED:
{ {
_RecalcScrollBars(); _RecalcScrollBars();
@@ -370,6 +396,11 @@ MemoryView::MessageReceived(BMessage* message)
} }
break; break;
} }
case MSG_VIEW_AUTOSCROLL:
{
_HandleAutoScroll();
break;
}
default: default:
{ {
BView::MessageReceived(message); BView::MessageReceived(message);
@@ -385,7 +416,78 @@ MemoryView::MouseDown(BPoint point)
if (!IsFocus()) if (!IsFocus())
MakeFocus(true); 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) { if (fTargetBlock != NULL) {
target_addr_t offset = fTargetAddress - fTargetBlock->BaseAddress(); target_addr_t offset = fTargetAddress - fTargetBlock->BaseAddress();
int32 lineNumber = 0; int32 lineNumber = 0;
if (fHexBlocksPerLine > 0) if (fHexBlocksPerLine > 0) {
lineNumber = offset / (fHexBlocksPerLine * (1 << (fHexMode - 1))); lineNumber = offset / (fHexBlocksPerLine
else if (fTextCharsPerLine > 0) * (_GetHexDigitsPerBlock() / 2));
} else if (fTextCharsPerLine > 0)
lineNumber = offset / fTextCharsPerLine; lineNumber = offset / fTextCharsPerLine;
float y = lineNumber * fLineHeight; float y = lineNumber * fLineHeight;
if (y < Bounds().top) if (y < Bounds().top)
ScrollTo(0.0, y); ScrollTo(0.0, y);
@@ -429,40 +533,23 @@ MemoryView::_RecalcScrollBars()
float max = 0.0; float max = 0.0;
BScrollBar *scrollBar = ScrollBar(B_VERTICAL); BScrollBar *scrollBar = ScrollBar(B_VERTICAL);
if (fTargetBlock != NULL) { if (fTargetBlock != NULL) {
BRect bounds = Bounds(); int32 hexDigits = _GetHexDigitsPerBlock();
// 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 sizeFactor = 1 + hexDigits; int32 sizeFactor = 1 + hexDigits;
if (fHexMode != HexModeNone) { _RecalcBounds();
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;
float hexWidth = fHexRight - fHexLeft;
int32 nybblesPerLine = int32(hexWidth / fCharWidth); int32 nybblesPerLine = int32(hexWidth / fCharWidth);
fHexBlocksPerLine = 0; fHexBlocksPerLine = 0;
fTextCharsPerLine = 0; fTextCharsPerLine = 0;
if (fHexMode != HexModeNone) { if (fHexMode != HexModeNone) {
fHexBlocksPerLine = nybblesPerLine / sizeFactor; fHexBlocksPerLine = nybblesPerLine / sizeFactor;
fHexBlocksPerLine &= ~1; fHexBlocksPerLine &= ~1;
fHexRight = fHexLeft + (fHexBlocksPerLine * sizeFactor
* fCharWidth);
if (fTextMode != TextModeNone) if (fTextMode != TextModeNone)
fTextCharsPerLine = fHexBlocksPerLine * hexDigits / 2; fTextCharsPerLine = fHexBlocksPerLine * hexDigits / 2;
} else if (fTextMode != TextModeNone) } else if (fTextMode != TextModeNone)
fTextCharsPerLine = int32(textWidth / fCharWidth); fTextCharsPerLine = int32((fTextRight - fTextLeft) / fCharWidth);
int32 lineCount = 0; int32 lineCount = 0;
float totalHeight = 0.0; float totalHeight = 0.0;
if (fHexBlocksPerLine > 0) { if (fHexBlocksPerLine > 0) {
@@ -473,6 +560,7 @@ MemoryView::_RecalcScrollBars()
totalHeight = lineCount * fLineHeight; totalHeight = lineCount * fLineHeight;
if (totalHeight > 0.0) { if (totalHeight > 0.0) {
BRect bounds = Bounds();
max = totalHeight - bounds.Height(); max = totalHeight - bounds.Height();
scrollBar->SetProportion(bounds.Height() / totalHeight); scrollBar->SetProportion(bounds.Height() / totalHeight);
scrollBar->SetSteps(fLineHeight, bounds.Height()); scrollBar->SetSteps(fLineHeight, bounds.Height());
@@ -488,7 +576,8 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize,
switch(fHexMode) { switch(fHexMode) {
case HexMode8BitInt: case HexMode8BitInt:
{ {
snprintf(buffer, bufferSize, "%02" B_PRIx8, *address); snprintf(buffer, bufferSize, "%02" B_PRIx8,
*((const uint8*)address));
break; break;
} }
case HexMode16BitInt: 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<BPopUpMenu> menuDeleter(menu);
ObjectDeleter<BMenuItem> itemDeleter;
ObjectDeleter<BMessage> 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 //#pragma mark - Listener
@@ -38,9 +38,9 @@ enum {
}; };
class BMessageRunner;
class Team; class Team;
class TeamMemoryBlock; class TeamMemoryBlock;
@@ -66,6 +66,9 @@ public:
virtual void MakeFocus(bool isFocused); virtual void MakeFocus(bool isFocused);
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual void MouseDown(BPoint point); virtual void MouseDown(BPoint point);
virtual void MouseMoved(BPoint point, uint32 transit,
const BMessage* dragMessage);
virtual void MouseUp(BPoint point);
void ScrollToSelection(); void ScrollToSelection();
virtual void TargetedByScrollView(BScrollView* scrollView); virtual void TargetedByScrollView(BScrollView* scrollView);
@@ -75,6 +78,22 @@ private:
void _GetNextHexBlock(char* buffer, void _GetNextHexBlock(char* buffer,
int32 bufferSize, const char* address); 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: private:
::Team* fTeam; ::Team* fTeam;
TeamMemoryBlock* fTargetBlock; TeamMemoryBlock* fTargetBlock;
@@ -87,6 +106,17 @@ private:
int32 fCurrentEndianMode; int32 fCurrentEndianMode;
int32 fHexMode; int32 fHexMode;
int32 fTextMode; int32 fTextMode;
float fHexLeft;
float fHexRight;
float fTextLeft;
float fTextRight;
int32 fSelectionBase;
int32 fSelectionStart;
int32 fSelectionEnd;
BMessageRunner* fScrollRunner;
bool fTrackingMouse;
Listener* fListener; Listener* fListener;
}; };
@@ -1,6 +1,6 @@
/* /*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. * 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. * Distributed under the terms of the MIT License.
*/ */
@@ -11,12 +11,17 @@
#include <new> #include <new>
#include <ControlLook.h> #include <ControlLook.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <Window.h>
#include "table/TableColumns.h" #include "table/TableColumns.h"
#include "Architecture.h" #include "Architecture.h"
#include "AutoDeleter.h"
#include "CpuState.h" #include "CpuState.h"
#include "GuiSettingsUtils.h" #include "GuiSettingsUtils.h"
#include "MessageCodes.h"
#include "Register.h" #include "Register.h"
#include "UiUtils.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<BPopUpMenu> menuDeleter(menu);
BMessage* message = new(std::nothrow)BMessage(MSG_SHOW_INSPECTOR_WINDOW);
if (message == NULL)
return;
message->AddUInt64("address", value.ToUInt64());
ObjectDeleter<BMessage> messageDeleter(message);
BMenuItem* item = new(std::nothrow)BMenuItem("Inspect", message);
if (item == NULL)
return;
messageDeleter.Detach();
ObjectDeleter<BMenuItem> 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 void
RegistersView::_Init() RegistersView::_Init()
{ {
@@ -1,5 +1,6 @@
/* /*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef REGISTERS_VIEW_H #ifndef REGISTERS_VIEW_H
@@ -35,6 +36,10 @@ private:
// TableListener // TableListener
virtual void TableRowInvoked(Table* table, int32 rowIndex); virtual void TableRowInvoked(Table* table, int32 rowIndex);
virtual void TableCellMouseDown(Table* table, int32 rowIndex,
int32 columnIndex, BPoint screenWhere,
uint32 buttons);
void _Init(); void _Init();
private: private:
@@ -2103,7 +2103,7 @@ status_t
VariablesView::_AddContextAction(const char* action, uint32 what, VariablesView::_AddContextAction(const char* action, uint32 what,
ContextActionList* actions, BMessage*& _message) ContextActionList* actions, BMessage*& _message)
{ {
_message = new BMessage(what); _message = new(std::nothrow) BMessage(what);
if (_message == NULL) if (_message == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
+1
View File
@@ -38,6 +38,7 @@ Application HaikuDepot :
MainWindow.cpp MainWindow.cpp
Model.cpp Model.cpp
PackageInfo.cpp PackageInfo.cpp
PackageInfoListener.cpp
PackageInfoView.cpp PackageInfoView.cpp
PackageListView.cpp PackageListView.cpp
PackageManager.cpp PackageManager.cpp
+34 -65
View File
@@ -8,6 +8,7 @@
#include <stdio.h> #include <stdio.h>
#include <Alert.h> #include <Alert.h>
#include <Autolock.h>
#include <Application.h> #include <Application.h>
#include <Button.h> #include <Button.h>
#include <Catalog.h> #include <Catalog.h>
@@ -39,8 +40,8 @@ MainWindow::MainWindow(BRect frame)
_BuildMenu(menuBar); _BuildMenu(menuBar);
fFilterView = new FilterView(fModel); fFilterView = new FilterView(fModel);
fPackageListView = new PackageListView(); fPackageListView = new PackageListView(fModel.Lock());
fPackageInfoView = new PackageInfoView(&fPackageManager); fPackageInfoView = new PackageInfoView(fModel.Lock(), &fPackageManager);
fSplitView = new BSplitView(B_VERTICAL, 5.0f); fSplitView = new BSplitView(B_VERTICAL, 5.0f);
@@ -87,14 +88,22 @@ MainWindow::MessageReceived(BMessage* message)
switch (message->what) { switch (message->what) {
case B_SIMPLE_DATA: case B_SIMPLE_DATA:
case B_REFS_RECEIVED: case B_REFS_RECEIVED:
// TODO: ?
break; break;
case MSG_PACKAGE_SELECTED: case MSG_PACKAGE_SELECTED:
{ {
int32 index; BString title;
if (message->FindInt32("index", &index) == B_OK if (message->FindString("title", &title) == B_OK) {
&& index >= 0 && index < fVisiblePackages.CountItems()) { int count = fVisiblePackages.CountItems();
_AdoptPackage(fVisiblePackages.ItemAtFast(index)); for (int i = 0; i < count; i++) {
const PackageInfoRef& package
= fVisiblePackages.ItemAtFast(i);
if (package.Get() != NULL && package->Title() == title) {
_AdoptPackage(package);
break;
}
}
} else { } else {
_ClearPackage(); _ClearPackage();
} }
@@ -154,15 +163,17 @@ MainWindow::_AdoptModel()
fPackageListView->Clear(); fPackageListView->Clear();
for (int32 i = 0; i < fVisiblePackages.CountItems(); i++) { for (int32 i = 0; i < fVisiblePackages.CountItems(); i++) {
BAutolock _(fModel.Lock());
fPackageListView->AddPackage(fVisiblePackages.ItemAtFast(i)); fPackageListView->AddPackage(fVisiblePackages.ItemAtFast(i));
} }
} }
void void
MainWindow::_AdoptPackage(const PackageInfo& package) MainWindow::_AdoptPackage(const PackageInfoRef& package)
{ {
fPackageInfoView->SetPackage(package); fPackageInfoView->SetPackage(package);
fModel.PopulatePackage(package);
} }
@@ -176,14 +187,17 @@ MainWindow::_ClearPackage()
void void
MainWindow::_InitDummyModel() MainWindow::_InitDummyModel()
{ {
// TODO: The Model could be filled from another thread by // TODO: The Model needs to be filled initially by the Package Kit APIs.
// sending messages which contain collected package information. // It already caches information locally. Error handlers need to be
// The Model could be cached on disk. // 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")); DepotInfo depot(B_TRANSLATE("Default"));
// WonderBrush // WonderBrush
PackageInfo wonderbrush( PackageInfoRef wonderbrush(new(std::nothrow) PackageInfo(
BitmapRef(new SharedBitmap(601), true), BitmapRef(new SharedBitmap(601), true),
"WonderBrush", "WonderBrush",
"2.1.2", "2.1.2",
@@ -196,24 +210,14 @@ MainWindow::_InitDummyModel()
"WonderBrush is YellowBites' software for doing graphics design " "WonderBrush is YellowBites' software for doing graphics design "
"on Haiku. It combines many great under-the-hood features with " "on Haiku. It combines many great under-the-hood features with "
"powerful tools and an efficient and intuitive interface.", "powerful tools and an efficient and intuitive interface.",
"2.1.2 - Initial Haiku release."); "2.1.2 - Initial Haiku release."), true);
wonderbrush.AddUserRating( wonderbrush->AddCategory(fModel.CategoryGraphics());
UserRating(UserInfo("humdinger"), 4.5f, wonderbrush->AddCategory(fModel.CategoryProductivity());
"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());
depot.AddPackage(wonderbrush); depot.AddPackage(wonderbrush);
// Paladin // Paladin
PackageInfo paladin( PackageInfoRef paladin(new(std::nothrow) PackageInfo(
BitmapRef(new SharedBitmap(602), true), BitmapRef(new SharedBitmap(602), true),
"Paladin", "Paladin",
"1.2.0", "1.2.0",
@@ -227,30 +231,13 @@ MainWindow::_InitDummyModel()
"The interface is streamlined, it has some features sorely " "The interface is streamlined, it has some features sorely "
"missing from BeIDE, like running a project in the Terminal, " "missing from BeIDE, like running a project in the Terminal, "
"and has a bundled text editor based upon Pe.", "and has a bundled text editor based upon Pe.",
""); ""), true);
paladin.AddUserRating( paladin->AddCategory(fModel.CategoryDevelopment());
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());
depot.AddPackage(paladin); depot.AddPackage(paladin);
// Sequitur // Sequitur
PackageInfo sequitur( PackageInfoRef sequitur(new(std::nothrow) PackageInfo(
BitmapRef(new SharedBitmap(604), true), BitmapRef(new SharedBitmap(604), true),
"Sequitur", "Sequitur",
"2.1.0", "2.1.0",
@@ -314,26 +301,8 @@ MainWindow::_InitDummyModel()
"pressure events. The new tool Broken Down Line uses this " "pressure events. The new tool Broken Down Line uses this "
"filter.\n\n" "filter.\n\n"
" * ''Note to filter developers:'' The filter API has changed. You " " * ''Note to filter developers:'' The filter API has changed. You "
"will need to recompile your filters."); "will need to recompile your filters."), true);
sequitur.AddUserRating( sequitur->AddCategory(fModel.CategoryAudio());
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());
depot.AddPackage(sequitur); depot.AddPackage(sequitur);
+1 -1
View File
@@ -35,7 +35,7 @@ private:
void _BuildMenu(BMenuBar* menuBar); void _BuildMenu(BMenuBar* menuBar);
void _AdoptModel(); void _AdoptModel();
void _AdoptPackage(const PackageInfo& package); void _AdoptPackage(const PackageInfoRef& package);
void _ClearPackage(); void _ClearPackage();
void _InitDummyModel(); void _InitDummyModel();
+101 -13
View File
@@ -7,6 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <Autolock.h>
#include <Catalog.h> #include <Catalog.h>
@@ -24,7 +25,7 @@ PackageFilter::~PackageFilter()
class AnyFilter : public PackageFilter { class AnyFilter : public PackageFilter {
public: public:
virtual bool AcceptsPackage(const PackageInfo& package) const virtual bool AcceptsPackage(const PackageInfoRef& package) const
{ {
return true; 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? // TODO: Maybe a PackageInfo ought to know the Depot it came from?
// But right now the same package could theoretically be provided // 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--) { for (int i = categories.CountItems() - 1; i >= 0; i--) {
const CategoryRef& category = categories.ItemAtFast(i); const CategoryRef& category = categories.ItemAtFast(i);
if (category.Get() == NULL) 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); 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) return fPackageListA.Contains(package)
|| fPackageListB.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 // Every search term must be found in one of the package texts
for (int32 i = fSearchTerms.CountItems() - 1; i >= 0; i--) { for (int32 i = fSearchTerms.CountItems() - 1; i >= 0; i--) {
const BString& term = fSearchTerms.ItemAtFast(i); const BString& term = fSearchTerms.ItemAtFast(i);
if (!_TextContains(package.Title(), term) if (!_TextContains(package->Title(), term)
&& !_TextContains(package.Publisher().Name(), term) && !_TextContains(package->Publisher().Name(), term)
&& !_TextContains(package.ShortDescription(), term) && !_TextContains(package->ShortDescription(), term)
&& !_TextContains(package.FullDescription(), term)) { && !_TextContains(package->FullDescription(), term)) {
return false; return false;
} }
} }
@@ -263,7 +268,7 @@ Model::CreatePackageList() const
const PackageList& packages = depot.Packages(); const PackageList& packages = depot.Packages();
for (int32 j = 0; j < packages.CountItems(); j++) { for (int32 j = 0; j < packages.CountItems(); j++) {
const PackageInfo& package = packages.ItemAtFast(j); const PackageInfoRef& package = packages.ItemAtFast(j);
if (fCategoryFilter->AcceptsPackage(package) if (fCategoryFilter->AcceptsPackage(package)
&& fSearchTermsFilter->AcceptsPackage(package)) { && fSearchTermsFilter->AcceptsPackage(package)) {
resultList.Add(package); resultList.Add(package);
@@ -283,7 +288,7 @@ Model::AddDepot(const DepotInfo& depot)
void void
Model::SetPackageState(const PackageInfo& package, PackageState state) Model::SetPackageState(const PackageInfoRef& package, PackageState state)
{ {
switch (state) { switch (state) {
default: default:
@@ -362,3 +367,86 @@ Model::SetSearchTerms(const BString& searchTerms)
fSearchTermsFilter.SetTo(filter, true); 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)
);
}
}
+12 -2
View File
@@ -5,6 +5,7 @@
#ifndef MODEL_H #ifndef MODEL_H
#define MODEL_H #define MODEL_H
#include <Locker.h>
#include "PackageInfo.h" #include "PackageInfo.h"
@@ -14,7 +15,7 @@ public:
virtual ~PackageFilter(); virtual ~PackageFilter();
virtual bool AcceptsPackage( virtual bool AcceptsPackage(
const PackageInfo& package) const = 0; const PackageInfoRef& package) const = 0;
}; };
typedef BReference<PackageFilter> PackageFilterRef; typedef BReference<PackageFilter> PackageFilterRef;
@@ -24,6 +25,9 @@ class Model {
public: public:
Model(); Model();
BLocker* Lock()
{ return &fLock; }
// !Returns new PackageInfoList from current parameters // !Returns new PackageInfoList from current parameters
PackageList CreatePackageList() const; PackageList CreatePackageList() const;
@@ -55,7 +59,7 @@ public:
{ return fProgressCategories; } { return fProgressCategories; }
void SetPackageState( void SetPackageState(
const PackageInfo& package, const PackageInfoRef& package,
PackageState state); PackageState state);
// Configure PackageFilters // Configure PackageFilters
@@ -63,7 +67,12 @@ public:
void SetDepot(const BString& depot); void SetDepot(const BString& depot);
void SetSearchTerms(const BString& searchTerms); void SetSearchTerms(const BString& searchTerms);
// Retrieve package information
void PopulatePackage(const PackageInfoRef& package);
private: private:
BLocker fLock;
DepotList fDepots; DepotList fDepots;
CategoryRef fCategoryAudio; CategoryRef fCategoryAudio;
@@ -84,6 +93,7 @@ private:
PackageList fUninstalledPackages; PackageList fUninstalledPackages;
PackageList fDownloadingPackages; PackageList fDownloadingPackages;
PackageList fUpdateablePackages; PackageList fUpdateablePackages;
PackageList fPopulatedPackages;
PackageFilterRef fCategoryFilter; PackageFilterRef fCategoryFilter;
BString fDepotFilter; BString fDepotFilter;
+51 -3
View File
@@ -535,7 +535,12 @@ PackageInfo::AddCategory(const CategoryRef& category)
bool bool
PackageInfo::AddUserRating(const UserRating& rating) 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 bool
PackageInfo::AddScreenshot(const BitmapRef& screenshot) 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 bool
DepotInfo::AddPackage(const PackageInfo& package) DepotInfo::AddPackage(const PackageInfoRef& package)
{ {
return fPackages.Add(package); return fPackages.Add(package);
} }
+19 -3
View File
@@ -10,6 +10,7 @@
#include <String.h> #include <String.h>
#include "List.h" #include "List.h"
#include "PackageInfoListener.h"
class BBitmap; class BBitmap;
@@ -181,7 +182,10 @@ typedef BReference<PackageCategory> CategoryRef;
typedef List<CategoryRef, false> CategoryList; typedef List<CategoryRef, false> CategoryList;
class PackageInfo { typedef List<PackageInfoListenerRef, false, 2> PackageListenerList;
class PackageInfo : public BReferenceable {
public: public:
PackageInfo(); PackageInfo();
PackageInfo(const BitmapRef& icon, PackageInfo(const BitmapRef& icon,
@@ -225,6 +229,14 @@ public:
const BitmapList& Screenshots() const const BitmapList& Screenshots() const
{ return fScreenshots; } { return fScreenshots; }
bool AddListener(
const PackageInfoListenerRef& listener);
void RemoveListener(
const PackageInfoListenerRef& listener);
private:
void _NotifyListeners(uint32 changes);
private: private:
BitmapRef fIcon; BitmapRef fIcon;
BString fTitle; BString fTitle;
@@ -236,10 +248,14 @@ private:
CategoryList fCategories; CategoryList fCategories;
UserRatingList fUserRatings; UserRatingList fUserRatings;
BitmapList fScreenshots; BitmapList fScreenshots;
PackageListenerList fListeners;
}; };
typedef List<PackageInfo, false> PackageList; typedef BReference<PackageInfo> PackageInfoRef;
typedef List<PackageInfoRef, false> PackageList;
enum PackageState { enum PackageState {
@@ -266,7 +282,7 @@ public:
const PackageList& Packages() const const PackageList& Packages() const
{ return fPackages; } { return fPackages; }
bool AddPackage(const PackageInfo& package); bool AddPackage(const PackageInfoRef& package);
private: private:
BString fName; BString fName;
@@ -0,0 +1,86 @@
/*
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "PackageInfoListener.h"
#include <stdio.h>
#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()
{
}
@@ -0,0 +1,61 @@
/*
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_INFO_LISTENER_H
#define PACKAGE_INFO_LISTENER_H
#include <Referenceable.h>
enum {
PKG_CHANGED_DESCRIPTION = 1 << 0,
PKG_CHANGED_RATINGS = 1 << 1,
PKG_CHANGED_SCREENSHOTS = 1 << 2,
// ...
};
class PackageInfo;
typedef BReference<PackageInfo> 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<PackageInfoListener> PackageInfoListenerRef;
#endif // PACKAGE_INFO_LISTENER_H
+110 -3
View File
@@ -8,6 +8,7 @@
#include <algorithm> #include <algorithm>
#include <stdio.h> #include <stdio.h>
#include <Autolock.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <Button.h> #include <Button.h>
#include <CardLayout.h> #include <CardLayout.h>
@@ -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 // #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(); fTitleView = new TitleView();
fPackageActionView = new PackageActionView(packageManager); fPackageActionView = new PackageActionView(packageManager);
@@ -1150,6 +1216,8 @@ PackageInfoView::PackageInfoView(PackageManager* packageManager)
PackageInfoView::~PackageInfoView() PackageInfoView::~PackageInfoView()
{ {
fPackageListener->SetPackage(PackageInfoRef(NULL));
delete fPackageListener;
} }
@@ -1163,6 +1231,35 @@ void
PackageInfoView::MessageReceived(BMessage* message) PackageInfoView::MessageReceived(BMessage* message)
{ {
switch (message->what) { 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: default:
BGroupView::MessageReceived(message); BGroupView::MessageReceived(message);
break; break;
@@ -1171,14 +1268,20 @@ PackageInfoView::MessageReceived(BMessage* message)
void void
PackageInfoView::SetPackage(const PackageInfo& package) PackageInfoView::SetPackage(const PackageInfoRef& packageRef)
{ {
BAutolock _(fModelLock);
const PackageInfo& package = *packageRef.Get();
fTitleView->SetPackage(package); fTitleView->SetPackage(package);
fPackageActionView->SetPackage(package); fPackageActionView->SetPackage(package);
fPagesView->SetPackage(package); fPagesView->SetPackage(package);
if (fPagesView->IsHidden(fPagesView)) if (fPagesView->IsHidden(fPagesView))
fPagesView->Show(); fPagesView->Show();
fPackageListener->SetPackage(packageRef);
} }
@@ -1191,5 +1294,9 @@ PackageInfoView::Clear()
if (!fPagesView->IsHidden(fPagesView)) if (!fPagesView->IsHidden(fPagesView))
fPagesView->Hide(); fPagesView->Hide();
BAutolock _(fModelLock);
fPackageListener->SetPackage(PackageInfoRef(NULL));
} }
+12 -2
View File
@@ -8,8 +8,10 @@
#include <GroupView.h> #include <GroupView.h>
#include "PackageInfo.h" #include "PackageInfo.h"
#include "PackageInfoListener.h"
class BLocker;
class TitleView; class TitleView;
class PackageActionView; class PackageActionView;
class PackageManager; class PackageManager;
@@ -23,19 +25,27 @@ enum {
class PackageInfoView : public BGroupView { class PackageInfoView : public BGroupView {
public: public:
PackageInfoView(PackageManager* packageManager); PackageInfoView(BLocker* modelLock,
PackageManager* packageManager);
virtual ~PackageInfoView(); virtual ~PackageInfoView();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
void SetPackage(const PackageInfo& package); void SetPackage(const PackageInfoRef& package);
void Clear(); void Clear();
private: private:
class Listener;
private:
BLocker* fModelLock;
TitleView* fTitleView; TitleView* fTitleView;
PackageActionView* fPackageActionView; PackageActionView* fPackageActionView;
PagesView* fPagesView; PagesView* fPagesView;
Listener* fPackageListener;
}; };
#endif // PACKAGE_INFO_VIEW_H #endif // PACKAGE_INFO_VIEW_H
+133 -19
View File
@@ -8,6 +8,7 @@
#include <algorithm> #include <algorithm>
#include <stdio.h> #include <stdio.h>
#include <Autolock.h>
#include <Catalog.h> #include <Catalog.h>
#include <ScrollBar.h> #include <ScrollBar.h>
#include <Window.h> #include <Window.h>
@@ -80,13 +81,58 @@ private:
class PackageRow : public BRow { class PackageRow : public BRow {
typedef BRow Inherited; typedef BRow Inherited;
public: public:
PackageRow(const PackageInfo& package); PackageRow(const PackageInfoRef& package,
PackageListener* listener);
virtual ~PackageRow();
const PackageInfo& Package() const const PackageInfoRef& Package() const
{ return fPackage; } { return fPackage; }
void UpdateRating();
private: 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)), 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 // Package icon and title
// NOTE: The icon BBitmap is referenced by the fPackage member. // NOTE: The icon BBitmap is referenced by the fPackage member.
const BBitmap* icon = NULL; const BBitmap* icon = NULL;
@@ -387,8 +440,7 @@ PackageRow::PackageRow(const PackageInfo& package)
SetField(new BBitmapStringField(icon, package.Title()), kTitleColumn); SetField(new BBitmapStringField(icon, package.Title()), kTitleColumn);
// Rating // Rating
RatingSummary summary = package.CalculateRatingSummary(); UpdateRating();
SetField(new RatingField(summary.averageRating), kRatingColumn);
// Description // Description
SetField(new BStringField(package.ShortDescription()), kDescriptionColumn); SetField(new BStringField(package.ShortDescription()), kDescriptionColumn);
@@ -400,6 +452,25 @@ PackageRow::PackageRow(const PackageInfo& package)
// Status // Status
// TODO: Fetch info about installed/deactivated/unintalled/... // TODO: Fetch info about installed/deactivated/unintalled/...
SetField(new BStringField("n/a"), kStatusColumn); 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 // #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, AddColumn(new PackageColumn(B_TRANSLATE("Name"), 150, 50, 300,
B_TRUNCATE_MIDDLE), kTitleColumn); B_TRUNCATE_MIDDLE), kTitleColumn);
@@ -511,6 +584,8 @@ PackageListView::PackageListView()
PackageListView::~PackageListView() PackageListView::~PackageListView()
{ {
Clear();
delete fPackageListener;
} }
@@ -525,6 +600,27 @@ void
PackageListView::MessageReceived(BMessage* message) PackageListView::MessageReceived(BMessage* message)
{ {
switch (message->what) { 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: default:
BColumnListView::MessageReceived(message); BColumnListView::MessageReceived(message);
break; break;
@@ -539,21 +635,16 @@ PackageListView::SelectionChanged()
BMessage message(MSG_PACKAGE_SELECTED); BMessage message(MSG_PACKAGE_SELECTED);
BRow* selected = CurrentSelection(); PackageRow* selected = dynamic_cast<PackageRow*>(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;
if (selected != NULL) if (selected != NULL)
index = IndexOf(selected); message.AddString("title", selected->Package()->Title());
message.AddInt32("index", index);
Window()->PostMessage(&message); Window()->PostMessage(&message);
} }
void void
PackageListView::AddPackage(const PackageInfo& package) PackageListView::AddPackage(const PackageInfoRef& package)
{ {
PackageRow* packageRow = _FindRow(package); PackageRow* packageRow = _FindRow(package);
@@ -561,8 +652,10 @@ PackageListView::AddPackage(const PackageInfo& package)
if (packageRow != NULL) if (packageRow != NULL)
return; return;
BAutolock _(fModelLock);
// create the row for this package // 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) // add the row, parent may be NULL (add at top level)
AddRow(packageRow); AddRow(packageRow);
@@ -575,7 +668,7 @@ PackageListView::AddPackage(const PackageInfo& package)
PackageRow* PackageRow*
PackageListView::_FindRow(const PackageInfo& package, PackageRow* parent) PackageListView::_FindRow(const PackageInfoRef& package, PackageRow* parent)
{ {
for (int32 i = CountRows(parent) - 1; i >= 0; i--) { for (int32 i = CountRows(parent) - 1; i >= 0; i--) {
PackageRow* row = dynamic_cast<PackageRow*>(RowAt(i, parent)); PackageRow* row = dynamic_cast<PackageRow*>(RowAt(i, parent));
@@ -592,3 +685,24 @@ PackageListView::_FindRow(const PackageInfo& package, PackageRow* parent)
return NULL; return NULL;
} }
PackageRow*
PackageListView::_FindRow(const BString& packageTitle, PackageRow* parent)
{
for (int32 i = CountRows(parent) - 1; i >= 0; i--) {
PackageRow* row = dynamic_cast<PackageRow*>(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;
}
+10 -3
View File
@@ -8,11 +8,13 @@
#include <ColumnListView.h> #include <ColumnListView.h>
#include <ColumnTypes.h> #include <ColumnTypes.h>
#include <Locker.h>
#include "PackageInfo.h" #include "PackageInfo.h"
class PackageRow; class PackageRow;
class PackageListener;
enum { enum {
MSG_PACKAGE_SELECTED = 'pkgs', MSG_PACKAGE_SELECTED = 'pkgs',
@@ -21,7 +23,7 @@ enum {
class PackageListView : public BColumnListView { class PackageListView : public BColumnListView {
public: public:
PackageListView(); PackageListView(BLocker* modelLock);
virtual ~PackageListView(); virtual ~PackageListView();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
@@ -29,15 +31,20 @@ public:
virtual void SelectionChanged(); virtual void SelectionChanged();
void AddPackage(const PackageInfo& package); void AddPackage(const PackageInfoRef& package);
private: private:
PackageRow* _FindRow(const PackageInfo& package, PackageRow* _FindRow(const PackageInfoRef& package,
PackageRow* parent = NULL); PackageRow* parent = NULL);
PackageRow* _FindRow(const BString& packageTitle,
PackageRow* parent = NULL);
private: private:
class ItemCountView; class ItemCountView;
BLocker* fModelLock;
ItemCountView* fItemCountView; ItemCountView* fItemCountView;
PackageListener* fPackageListener;
}; };
#endif // PACKAGE_LIST_VIEW_H #endif // PACKAGE_LIST_VIEW_H
@@ -0,0 +1,3 @@
SubDir HAIKU_TOP src bin makebootable platform u-boot ;
BinCommand makebootable : makebootable.cpp ;
@@ -0,0 +1,6 @@
int
main()
{
return 0;
}
+1 -1
View File
@@ -105,6 +105,7 @@ static const media_type kMediaTypes[] = {
{ IFM_100_TX, "100baseTX", "100 MBit, 100BASE-TX" }, { IFM_100_TX, "100baseTX", "100 MBit, 100BASE-TX" },
{ IFM_1000_T, "1000baseT", "1 GBit, 1000BASE-T" }, { IFM_1000_T, "1000baseT", "1 GBit, 1000BASE-T" },
{ IFM_1000_SX, "1000baseSX", "1 GBit, 1000BASE-SX" }, { IFM_1000_SX, "1000baseSX", "1 GBit, 1000BASE-SX" },
{ IFM_10G_T, "10GbaseT", "10 GBit, 10GBASE-T" },
{ -1, NULL, NULL } { -1, NULL, NULL }
}, },
{ {
@@ -1012,4 +1013,3 @@ main(int argc, char** argv)
list_interfaces(name); list_interfaces(name);
return 0; return 0;
} }
+2
View File
@@ -12,3 +12,5 @@ resource(5, "META:EXTENS") message(234) {
"extensions" = "MP3", "extensions" = "MP3",
"type" = "audio/mpeg" "type" = "audio/mpeg"
}; };
resource(6, "META:SNIFF_RULE") "0.50 (0xfffb|0xfffa|\"ID3\")";
+18 -3
View File
@@ -500,9 +500,7 @@ BRow::SetField(BField* field, int32 logicalFieldIndex)
if (NULL != fList) { if (NULL != fList) {
ValidateField(field, logicalFieldIndex); ValidateField(field, logicalFieldIndex);
BRect inv; Invalidate();
fList->GetRowRect(this, &inv);
fList->Invalidate(inv);
} }
fFields.AddItem(field, logicalFieldIndex); fFields.AddItem(field, logicalFieldIndex);
@@ -530,6 +528,14 @@ BRow::IsSelected() const
} }
void
BRow::Invalidate()
{
if (fList != NULL)
fList->InvalidateRow(this);
}
void void
BRow::ValidateFields() const BRow::ValidateFields() const
{ {
@@ -1340,6 +1346,15 @@ BColumnListView::Clear()
} }
void
BColumnListView::InvalidateRow(BRow* row)
{
BRect updateRect;
GetRowRect(row, &updateRect);
fOutlineView->Invalidate(updateRect);
}
void void
BColumnListView::SetFont(const BFont* font, uint32 mask) BColumnListView::SetFont(const BFont* font, uint32 mask)
{ {
+7 -4
View File
@@ -1037,10 +1037,13 @@ BListView::ScrollToSelection()
if (Bounds().Contains(itemFrame)) if (Bounds().Contains(itemFrame))
return; return;
if (itemFrame.top < Bounds().top) float scrollPos = itemFrame.top < Bounds().top ?
ScrollTo(itemFrame.left, itemFrame.top); itemFrame.top : itemFrame.bottom - Bounds().Height();
else
ScrollTo(itemFrame.left, itemFrame.bottom - Bounds().Height()); if (itemFrame.top - scrollPos < Bounds().top)
scrollPos = itemFrame.top;
ScrollTo(itemFrame.left, scrollPos);
} }
@@ -583,8 +583,6 @@ ModulesView::DetachedFromWindow()
void void
ModulesView::AttachedToWindow() ModulesView::AttachedToWindow()
{ {
PopulateScreenSaverList();
fScreenSaversListView->SetTarget(this); fScreenSaversListView->SetTarget(this);
fTestButton->SetTarget(this); fTestButton->SetTarget(this);
fAddButton->SetTarget(this); fAddButton->SetTarget(this);
@@ -594,8 +592,7 @@ ModulesView::AttachedToWindow()
void void
ModulesView::AllAttached() ModulesView::AllAttached()
{ {
fScreenSaversListView->ScrollToSelection(); PopulateScreenSaverList();
// This only works after the list view is attached
fScreenSaversListView->Invoke(new BMessage(kMsgSaverSelected)); fScreenSaversListView->Invoke(new BMessage(kMsgSaverSelected));
} }
+1 -1
View File
@@ -152,7 +152,7 @@ actions BuildUImageScript1
rule BuildUBootSDImage image : files rule BuildUBootSDImage image : files
{ {
Depends $(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_SIZE on $(image) = $(HAIKU_BOARD_SDIMAGE_SIZE) ;
SDIMAGE_FDISK on $(image) = $(HOST_SFDISK) ; SDIMAGE_FDISK on $(image) = $(HOST_SFDISK) ;
SDIMAGE_FDISK_SCRIPT on $(image) = SDIMAGE_FDISK_SCRIPT on $(image) =
+17 -3
View File
@@ -5,10 +5,12 @@
#include <KernelExport.h> #include <KernelExport.h>
#include <boot/platform.h>
#include <boot/disk_identifier.h>
#include <boot/vfs.h> #include <boot/vfs.h>
#include <boot/stdio.h> #include <boot/platform.h>
#include <boot/stage2.h> #include <boot/stage2.h>
#include <boot/stdio.h>
#define TRACE_DEVICES #define TRACE_DEVICES
#ifdef TRACE_DEVICES #ifdef TRACE_DEVICES
@@ -73,6 +75,18 @@ platform_add_block_devices(stage2_args *args, NodeList *devicesList)
status_t status_t
platform_register_boot_device(Node *device) 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; return B_OK;
} }
+1 -1
View File
@@ -55,7 +55,7 @@ image_multi_getimg(struct image_header *image, uint32 idx, uint32 *data, uint32
*size = ntohl(sizes[i]); *size = ntohl(sizes[i]);
return true; return true;
} }
base += ntohl(sizes[i]); base += (ntohl(sizes[i]) + 3) & ~3;
} }
return false; return false;
} }
+2 -2
View File
@@ -227,8 +227,8 @@ FUNCTION(arch_debug_call_with_fault_handler):
// Set fault handler address, and fault handler stack pointer address. We // 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. // don't need to save the previous values, since that's done by the caller.
ldr r4, =1f ldr r4, =1f
str r4, [ r0, #CPU_ENT_fault_handler ] str r4, [r0, #CPU_ENT_fault_handler]
str sp, [ r0, #CPU_ENT_fault_handler_stack_pointer ] str sp, [r0, #CPU_ENT_fault_handler_stack_pointer]
mov r4, r1 mov r4, r1
// call the function // call the function
+54 -18
View File
@@ -35,35 +35,63 @@
#define PXA_OSSR 0x05 #define PXA_OSSR 0x05
#define PXA_OIER 0x07 #define PXA_OIER 0x07
#define PXA_OSCR4 0x10 #define PXA_OSCR4 0x10
#define PXA_OSCR5 0x11
#define PXA_OSMR4 0x20 #define PXA_OSMR4 0x20
#define PXA_OSMR5 0x21
#define PXA_OMCR4 0x30 #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; #define US2S(bt) ((bt) / 1000000ULL)
static uint32 *sPxaTimersBase; #define US2MS(bt) ((bt) / 1000ULL)
static area_id sPxaTimersArea = B_ERROR;
static uint32 *sPxaTimersBase = NULL;
static bigtime_t sSystemTime = 0;
static int32 static int32
pxa_timer_interrupt(void *data) pxa_timer_interrupt(void *data)
{ {
int32 ret = timer_interrupt(); if (sPxaTimersBase[PXA_OSSR] & (1 << 4)) {
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 void
arch_timer_set_hardware_timer(bigtime_t timeout) 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) { if (timeout & ~UINT_MAX) {
sPxaTimersBase[PXA_OIER] |= (1 << 4); // Does not fit, so scale resolution down to milliseconds
sPxaTimersBase[PXA_OMCR4] = 4; // set to exactly single milisecond resolution if (US2MS(timeout) & ~UINT_MAX) {
sPxaTimersBase[PXA_OSMR4] = timeout; // Still does not fit, scale down to seconds as last ditch attempt
sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again 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")); TRACE(("arch_timer_clear_hardware_timer\n"));
if (sPxaTimersBase) { sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer
sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer sPxaTimersBase[PXA_OIER] &= ~(1 << 4);
sPxaTimersBase[PXA_OIER] &= ~(4 << 1);
}
} }
int int
arch_init_timer(kernel_args *args) arch_init_timer(kernel_args *args)
{ {
@@ -88,9 +113,20 @@ arch_init_timer(kernel_args *args)
if (sPxaTimersArea < 0) if (sPxaTimersArea < 0)
return sPxaTimersArea; 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); install_io_interrupt_handler(PXA_TIMERS_INTERRUPT, &pxa_timer_interrupt, NULL, 0);
return B_OK; return B_OK;
} }
bigtime_t
system_time(void)
{
return (sPxaTimersBase != NULL) ?
sSystemTime + sPxaTimersBase[PXA_OSCR5] :
0ULL;
}
-9
View File
@@ -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; return B_OK;
} }
@@ -60,10 +60,8 @@ X86PagingMethod64Bit::Init(kernel_args* args,
fKernelVirtualPML4 = (uint64*)(addr_t)args->arch_args.vir_pgdir; fKernelVirtualPML4 = (uint64*)(addr_t)args->arch_args.vir_pgdir;
// if availalbe enable NX-bit (No eXecute) // if availalbe enable NX-bit (No eXecute)
if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) { if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD))
x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) call_all_cpus_sync(&_EnableExecutionDisable, NULL);
| IA32_MSR_EFER_NX);
}
// Ensure that the user half of the address space is clear. This removes // Ensure that the user half of the address space is clear. This removes
// the temporary identity mapping made by the boot loader. // the temporary identity mapping made by the boot loader.
@@ -384,3 +382,11 @@ X86PagingMethod64Bit::PutPageTableEntryInTable(uint64* entry,
SetTableEntry(entry, page); 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);
}
@@ -149,10 +149,8 @@ struct X86PagingMethodPAE::ToPAESwitcher {
call_all_cpus_sync(&_EnablePAE, (void*)(addr_t)physicalPDPT); call_all_cpus_sync(&_EnablePAE, (void*)(addr_t)physicalPDPT);
// if availalbe enable NX-bit (No eXecute) // if availalbe enable NX-bit (No eXecute)
if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) { if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD))
x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) call_all_cpus_sync(&_EnableExecutionDisable, NULL);
| IA32_MSR_EFER_NX);
}
// set return values // set return values
_virtualPDPT = pdpt; _virtualPDPT = pdpt;
@@ -173,6 +171,12 @@ private:
x86_write_cr4(x86_read_cr4() | IA32_CR4_PAE | IA32_CR4_GLOBAL_PAGES); 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) void _TranslatePageTable(addr_t virtualBase)
{ {
page_table_entry* entry = &fPageHole[virtualBase / B_PAGE_SIZE]; page_table_entry* entry = &fPageHole[virtualBase / B_PAGE_SIZE];
@@ -2280,7 +2280,6 @@ device_manager_init(struct kernel_args* args)
dm_init_io_resources(); dm_init_io_resources();
recursive_lock_init(&sLock, "device manager"); recursive_lock_init(&sLock, "device manager");
init_node_tree();
register_generic_syscall(DEVICE_MANAGER_SYSCALLS, control_device_manager, register_generic_syscall(DEVICE_MANAGER_SYSCALLS, control_device_manager,
1, 0); 1, 0);
@@ -2300,6 +2299,9 @@ device_manager_init(struct kernel_args* args)
"dump an I/O operation"); "dump an I/O operation");
add_debugger_command("io_buffer", &dump_io_buffer, "dump an I/O buffer"); 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"); add_debugger_command("dma_buffer", &dump_dma_buffer, "dump a DMA buffer");
init_node_tree();
return B_OK; return B_OK;
} }
-2
View File
@@ -11,8 +11,6 @@ SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o : KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
atomic.S atomic.S
byteorder.S byteorder.S
# system_time_asm.S
system_time.c
generic_system_time_nsecs.cpp generic_system_time_nsecs.cpp
+21 -68
View File
@@ -164,83 +164,36 @@ FUNCTION(atomic_get):
bx lr bx lr
FUNCTION_END(atomic_get) 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) */ /* int64 atomic_add64(vint64 *value, int64 addValue) */
//FUNCTION(atomic_add64): FUNCTION(atomic_add64):
// movem.l %d2-%d3/%a2,-(%a7) bx lr
// move.l (4,%a7),%a2 FUNCTION_END(atomic_add64)
// 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)
/* int64 atomic_and64(vint64 *value, int64 andValue) */ /* int64 atomic_and64(vint64 *value, int64 andValue) */
//FUNCTION(atomic_and64): FUNCTION(atomic_and64):
//FUNCTION_END(atomic_and64) bx lr
FUNCTION_END(atomic_and64)
/* int64 atomic_or64(vint64 *value, int64 orValue) */ /* int64 atomic_or64(vint64 *value, int64 orValue) */
//FUNCTION(atomic_or64): FUNCTION(atomic_or64):
//FUNCTION_END(atomic_or64) bx lr
FUNCTION_END(atomic_or64)
/* int64 atomic_set64(vint64 *value, int64 newValue) */ /* int64 atomic_set64(vint64 *value, int64 newValue) */
//FUNCTION(atomic_set64): FUNCTION(atomic_set64):
// movem.l %d2-%d3/%a2,-(%a7) bx lr
// move.l (4,%a7),%a2 FUNCTION_END(atomic_set64)
// 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)
/* int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) */ /* int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) */
//FUNCTION(atomic_test_and_set64): FUNCTION(atomic_test_and_set64):
// movem.l %d2-%d3/%a2,-(%a7) bx lr
// move.l (4,%a7),%a2 FUNCTION_END(atomic_test_and_set64)
// 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)
/* int64 atomic_get64(vint64 *value) */ /* int64 atomic_get64(vint64 *value) */
//FUNCTION(atomic_get64): FUNCTION(atomic_get64):
// movem.l %d2-%d3/%a2,-(%a7) bx lr
// move.l (4,%a7),%a2 FUNCTION_END(atomic_get64)
// 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)
@@ -12,6 +12,8 @@
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <Debug.h>
#include <thread_defs.h> #include <thread_defs.h>
@@ -105,6 +107,8 @@ pthread_attr_setstacksize(pthread_attr_t *_attr, size_t stacksize)
if (_attr == NULL || (attr = *_attr) == NULL) if (_attr == NULL || (attr = *_attr) == NULL)
return B_BAD_VALUE; 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) if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -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 <build>makebootable :
makebootable.cpp
$(hostPlatformSources)
: $(HOST_LIBBE) $(HOST_LIBSTDC++) $(HOST_LIBSUPC++)
;
BuildPlatformMain <build>makebootable : makebootable.cpp : $(HOST_LIBSTDC++) ;
+10 -1
View File
@@ -1,4 +1,13 @@
SubDir HAIKU_TOP src tools translation bitsinfo ; 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
;
+33 -23
View File
@@ -38,10 +38,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ByteOrder.h> #include <ByteOrder.h>
#include <Catalog.h>
#include <File.h> #include <File.h>
#include <TranslatorFormats.h> #include <TranslatorFormats.h>
#include <StorageDefs.h> #include <StorageDefs.h>
#undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "bitsinfo"
struct ColorSpaceName { struct ColorSpaceName {
color_space id; color_space id;
const char *name; const char *name;
@@ -62,7 +66,8 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
// read in the rest of the header // read in the rest of the header
ssize_t size = sizeof(TranslatorBitmap); ssize_t size = sizeof(TranslatorBitmap);
if (file.Read(reinterpret_cast<uint8 *> (&header), size) != size) { if (file.Read(reinterpret_cast<uint8 *> (&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; return;
} }
if (!bdumppixels) if (!bdumppixels)
@@ -72,28 +77,29 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
// convert to host byte order // convert to host byte order
if (swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap), if (swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap),
B_SWAP_BENDIAN_TO_HOST) != B_OK) { 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; 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; const uint32 kbitsmagic = 0x62697473UL;
// in ASCII, this number looks like "bits" // in ASCII, this number looks like "bits"
printf("magic number: 0x%.8lx ", header.magic);
if (header.magic == kbitsmagic) if (header.magic == kbitsmagic)
printf("(valid)\n"); printf(B_TRANSLATE("magic number: 0x%.8lx (valid)\n"),
header.magic);
else else
printf("(INVALID, should be: 0x%.8lx)\n", printf(B_TRANSLATE("magic number: 0x%.8lx (INVALID, should be: "
kbitsmagic); "0x%.8lx)\n"), header.magic, kbitsmagic);
printf("bounds: (%f, %f, %f, %f)\n", printf(B_TRANSLATE("bounds: (%f, %f, %f, %f)\n"),
header.bounds.left, header.bounds.top, header.bounds.left, header.bounds.top,
header.bounds.right, header.bounds.bottom); header.bounds.right, header.bounds.bottom);
printf("dimensions: %d x %d\n", printf(B_TRANSLATE("dimensions: %d x %d\n"),
static_cast<int>(header.bounds.Width() + 1), static_cast<int>(header.bounds.Width() + 1),
static_cast<int>(header.bounds.Height() + 1)); static_cast<int>(header.bounds.Height() + 1));
printf("bytes per row: %u\n", printf(B_TRANSLATE("bytes per row: %u\n"),
static_cast<unsigned int>(header.rowBytes)); static_cast<unsigned int>(header.rowBytes));
// print out colorspace if it matches an item in the list // print out colorspace if it matches an item in the list
@@ -149,15 +155,15 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
int32 i; int32 i;
for (i = 0; i < kncolorspaces; i++) { for (i = 0; i < kncolorspaces; i++) {
if (header.colors == colorspaces[i].id) { 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; break;
} }
} }
if (i == kncolorspaces) if (i == kncolorspaces)
printf("color space: Unknown (0x%.8lx)\n", printf(B_TRANSLATE("color space: Unknown (0x%.8lx)\n"),
static_cast<unsigned long>(header.colors)); static_cast<unsigned long>(header.colors));
printf("data size: %u\n", printf(B_TRANSLATE("data size: %u\n"),
static_cast<unsigned int>(header.dataSize)); static_cast<unsigned int>(header.dataSize));
if (bdumppixels) { if (bdumppixels) {
@@ -178,18 +184,19 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
break; break;
default: default:
printf("Sorry, %s isn't supported yet" printf(B_TRANSLATE("Sorry, %s isn't supported yet"
" for this color space\n", kpixels); " for this color space\n"), kpixels);
return; return;
} }
uint8 *prow = new uint8[header.rowBytes]; uint8 *prow = new uint8[header.rowBytes];
if (!prow) { if (!prow) {
printf("Error: Not enough memory for row buffer\n"); printf(B_TRANSLATE("Error: Not enough memory for row "
"buffer\n"));
return; return;
} }
ssize_t ret, n; ssize_t ret, n;
uint32 totalbytes = 0; 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) { while ((ret = file.Read(prow, header.rowBytes)) > 0) {
n = 0; n = 0;
while (n < ret) { while (n < ret) {
@@ -205,18 +212,21 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
} }
} else } else
printf("Error opening %s\n", filepath); printf(B_TRANSLATE_COMMENT("Error opening %s\n",
"file path is opening"), filepath);
} }
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
printf("\nbitsinfo - reports information about a Be bitmap (\"bits\") image\n"); printf(B_TRANSLATE("\nbitsinfo - reports information about a Be "
printf("\nUsage:\n"); "bitmap (\"bits\") image\n"));
printf("bitsinfo [options] filename.bits\n\n"); printf(B_TRANSLATE("\nUsage:\n"));
printf("Options:\n\n"); printf(B_TRANSLATE("bitsinfo [options] filename.bits\n\n"));
printf("\t%s \t print RGB color for each pixel\n", kpixels); printf(B_TRANSLATE("Options:\n\n"));
printf(B_TRANSLATE("\t%s \t print RGB color for each pixel\n"),
kpixels);
} }
else { else {
int32 first = 1; int32 first = 1;
@@ -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;
+8 -1
View File
@@ -1,4 +1,11 @@
SubDir HAIKU_TOP src tools translation bmpinfo ; 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
;
+60 -39
View File
@@ -36,10 +36,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ByteOrder.h> #include <ByteOrder.h>
#include <Catalog.h>
#include <File.h> #include <File.h>
#include <TranslatorFormats.h> #include <TranslatorFormats.h>
#include <StorageDefs.h> #include <StorageDefs.h>
#undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "bmpinfo"
#define BMP_NO_COMPRESS 0 #define BMP_NO_COMPRESS 0
#define BMP_RLE8_COMPRESS 1 #define BMP_RLE8_COMPRESS 1
#define BMP_RLE4_COMPRESS 2 #define BMP_RLE4_COMPRESS 2
@@ -82,7 +86,7 @@ print_bmp_info(BFile &file)
ssize_t size = 14; ssize_t size = 14;
if (file.Read(buf, size) != size) { 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; return;
} }
@@ -96,16 +100,18 @@ print_bmp_info(BFile &file)
swap_data(B_UINT32_TYPE, (reinterpret_cast<uint8 *> (&fh)) + 2, swap_data(B_UINT32_TYPE, (reinterpret_cast<uint8 *> (&fh)) + 2,
12, B_SWAP_LENDIAN_TO_HOST); 12, B_SWAP_LENDIAN_TO_HOST);
printf("\nFile Header:\n"); printf(B_TRANSLATE("\nFile Header:\n"));
printf(" magic: 0x%.4x (should be: 0x424d)\n", fh.magic); printf(B_TRANSLATE(" magic: 0x%.4x (should be: 0x424d)\n"), fh.magic);
printf(" file size: 0x%.8lx (%lu)\n", fh.fileSize, fh.fileSize); printf(B_TRANSLATE(" file size: 0x%.8lx (%lu)\n"), fh.fileSize,
printf(" reserved: 0x%.8lx (should be: 0x%.8x)\n", fh.reserved, 0); fh.fileSize);
printf("data offset: 0x%.8lx (%lu) (should be: >= 54 for MS format " printf(B_TRANSLATE(" reserved: 0x%.8lx (should be: 0x%.8x)\n"),
"and >= 26 for OS/2 format)\n", fh.dataOffset, fh.dataOffset); 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; uint32 headersize = 0;
if (file.Read(&headersize, 4) != 4) { 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; return;
} }
swap_data(B_UINT32_TYPE, &headersize, 4, B_SWAP_LENDIAN_TO_HOST); swap_data(B_UINT32_TYPE, &headersize, 4, B_SWAP_LENDIAN_TO_HOST);
@@ -115,7 +121,7 @@ print_bmp_info(BFile &file)
MSInfoHeader msh; MSInfoHeader msh;
msh.size = headersize; msh.size = headersize;
if (file.Read(reinterpret_cast<uint8 *> (&msh) + 4, 36) != 36) { if (file.Read(reinterpret_cast<uint8 *> (&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; return;
} }
@@ -123,22 +129,33 @@ print_bmp_info(BFile &file)
swap_data(B_UINT32_TYPE, reinterpret_cast<uint8 *> (&msh) + 4, 36, swap_data(B_UINT32_TYPE, reinterpret_cast<uint8 *> (&msh) + 4, 36,
B_SWAP_LENDIAN_TO_HOST); B_SWAP_LENDIAN_TO_HOST);
printf("\nMS Info Header:\n"); printf(B_TRANSLATE("\nMS Info Header:\n"));
printf(" header size: 0x%.8lx (%lu) (should be: 40)\n", msh.size, msh.size); printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: "
printf(" width: %lu\n", msh.width); "40)\n"), msh.size, msh.size);
printf(" height: %lu\n", msh.height); printf(B_TRANSLATE(" width: %lu\n"), msh.width);
printf(" planes: %u (should be: 1)\n", msh.planes); printf(B_TRANSLATE(" height: %lu\n"), msh.height);
printf(" bits per pixel: %u (should be: 1,4,8,16,24 or 32)\n", msh.bitsperpixel); printf(B_TRANSLATE(" planes: %u (should be: 1)\n"),
printf(" compression: %s (%lu)\n", msh.planes);
((msh.compression == BMP_NO_COMPRESS) ? ("none") : printf(B_TRANSLATE(" bits per pixel: %u (should be: 1,4,8,16,24 or "
((msh.compression == BMP_RLE8_COMPRESS) ? ("RLE 8") : "32)\n"), msh.bitsperpixel);
((msh.compression == BMP_RLE4_COMPRESS) ? ("RLE 4") : if (msh.compression == BMP_NO_COMPRESS)
("unknown")))), msh.compression); printf(B_TRANSLATE(" compression: none (%lu)\n"),
printf(" image size: 0x%.8lx (%lu)\n", msh.imagesize, msh.imagesize); msh.compression);
printf(" x pixels/meter: %lu\n", msh.xpixperm); else if (msh.compression == BMP_RLE8_COMPRESS)
printf(" y pixels/meter: %lu\n", msh.ypixperm); printf(B_TRANSLATE(" compression: RLE8 (%lu)\n"),
printf(" colors used: %lu\n", msh.colorsused); msh.compression);
printf("colors important: %lu\n", msh.colorsimportant); 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)) { } else if (headersize == sizeof(OS2InfoHeader)) {
// OS/2 format // OS/2 format
@@ -146,7 +163,8 @@ print_bmp_info(BFile &file)
OS2InfoHeader os2; OS2InfoHeader os2;
os2.size = headersize; os2.size = headersize;
if (file.Read(reinterpret_cast<uint8 *> (&os2) + 4, 8) != 8) { if (file.Read(reinterpret_cast<uint8 *> (&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; return;
} }
@@ -154,17 +172,18 @@ print_bmp_info(BFile &file)
swap_data(B_UINT32_TYPE, reinterpret_cast<uint8 *> (&os2) + 4, 8, swap_data(B_UINT32_TYPE, reinterpret_cast<uint8 *> (&os2) + 4, 8,
B_SWAP_LENDIAN_TO_HOST); B_SWAP_LENDIAN_TO_HOST);
printf("\nOS/2 Info Header:\n"); printf(B_TRANSLATE("\nOS/2 Info Header:\n"));
printf(" header size: 0x%.8lx (%lu) (should be: 12)\n", os2.size, os2.size); printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: 12)\n"),
printf(" width: %u\n", os2.width); os2.size, os2.size);
printf(" height: %u\n", os2.height); printf(B_TRANSLATE(" width: %u\n"), os2.width);
printf(" planes: %u (should be: 1)\n", os2.planes); printf(B_TRANSLATE(" height: %u\n"), os2.height);
printf("bits per pixel: %u (should be: 1,4,8 or 24)\n", 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); os2.bitsperpixel);
} else } else
printf("Error: info header size (%lu) does not match MS or OS/2 " printf(B_TRANSLATE("Error: info header size (%lu) does not match MS "
"info header size\n", headersize); "or OS/2 info header size\n"), headersize);
} }
int int
@@ -173,18 +192,20 @@ main(int argc, char **argv)
printf("\n"); printf("\n");
if (argc == 1) { if (argc == 1) {
printf("bmpinfo - reports information about a BMP image file\n"); printf(B_TRANSLATE("bmpinfo - reports information about a BMP image "
printf("\nUsage:\n"); "file\n"));
printf("bmpinfo filename.bmp\n"); printf(B_TRANSLATE("\nUsage:\n"));
printf(B_TRANSLATE("bmpinfo filename.bmp\n"));
} }
else { else {
BFile file; BFile file;
for (int32 i = 1; i < argc; i++) { for (int32 i = 1; i < argc; i++) {
if (file.SetTo(argv[i], B_READ_ONLY) != B_OK) 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 { 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); print_bmp_info(file);
} }
} }
@@ -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;
+10 -1
View File
@@ -1,4 +1,13 @@
SubDir HAIKU_TOP src tools translation tgainfo ; 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
;
+137 -78
View File
@@ -36,10 +36,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ByteOrder.h> #include <ByteOrder.h>
#include <Catalog.h>
#include <File.h> #include <File.h>
#include <TranslatorFormats.h> #include <TranslatorFormats.h>
#include <StorageDefs.h> #include <StorageDefs.h>
#undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "tgainfo"
#define max(x,y) ((x > y) ? x : y) #define max(x,y) ((x > y) ? x : y)
#define DATA_BUFFER_SIZE 64 #define DATA_BUFFER_SIZE 64
@@ -99,8 +103,8 @@ const char *
colormaptype(uint8 n) colormaptype(uint8 n)
{ {
switch (n) { switch (n) {
case 0: return "No colormap"; case 0: return B_TRANSLATE("No colormap");
case 1: return "colormap"; case 1: return B_TRANSLATE("colormap");
} }
return "unknown"; return "unknown";
} }
@@ -109,15 +113,16 @@ const char *
imagetype(uint8 n) imagetype(uint8 n)
{ {
switch (n) { switch (n) {
case 0: return "No Image Data"; case 0: return B_TRANSLATE("No Image Data");
case 1: return "colormap"; case 1: return B_TRANSLATE("colormap");
case 2: return "true color"; case 2: return B_TRANSLATE("true color");
case 3: return "grayscale"; case 3: return B_TRANSLATE("grayscale");
case 9: return "RLE colormap"; case 9: return B_TRANSLATE("RLE colormap");
case 10: return "RLE true color"; case 10: return B_TRANSLATE("RLE true color");
case 11: return "RLE grayscale"; case 11: return B_TRANSLATE("RLE grayscale");
default: break;
} }
return "unknown"; return B_TRANSLATE("unknown");
} }
uint16 uint16
@@ -140,7 +145,7 @@ print_tga_info(BFile &file)
// read in TGA headers // read in TGA headers
ssize_t size = TGA_HEADERS_SIZE; ssize_t size = TGA_HEADERS_SIZE;
if (size > 0 && file.Read(buf, size) != 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; return;
} }
@@ -150,12 +155,15 @@ print_tga_info(BFile &file)
fh.colormaptype = buf[1]; fh.colormaptype = buf[1];
fh.imagetype = buf[2]; fh.imagetype = buf[2];
printf("\nFile Header:\n"); printf(B_TRANSLATE("\nFile Header:\n"));
printf(" id length: %d\n", fh.idlength); printf(B_TRANSLATE(" id length: %d\n"), static_cast<int>(fh.idlength));
printf("colormap type: %d (%s)\n", fh.colormaptype, printf(B_TRANSLATE("colormap type: %d (%s)\n"),
colormaptype(fh.colormaptype)); static_cast<int>(fh.colormaptype),
printf(" image type: %d (%s)\n", fh.imagetype, imagetype(fh.imagetype)); static_cast<const char *>(colormaptype(fh.colormaptype)));
printf(B_TRANSLATE(" image type: %d (%s)\n"),
static_cast<int>(fh.imagetype),
static_cast<const char *>(imagetype(fh.imagetype)));
// TGA color map spec // TGA color map spec
@@ -164,10 +172,13 @@ print_tga_info(BFile &file)
mapspec.length = tga_uint16(reinterpret_cast<char *>(buf), 5); mapspec.length = tga_uint16(reinterpret_cast<char *>(buf), 5);
mapspec.entrysize = buf[7]; mapspec.entrysize = buf[7];
printf("\nColormap Spec:\n"); printf(B_TRANSLATE("\nColormap Spec:\n"));
printf("first entry: %d\n", mapspec.firstentry); printf(B_TRANSLATE("first entry: %d\n"),
printf(" length: %d\n", mapspec.length); static_cast<int>(mapspec.firstentry));
printf(" entry size: %d\n", mapspec.entrysize); printf(B_TRANSLATE(" length: %d\n"),
static_cast<int>(mapspec.length));
printf(B_TRANSLATE(" entry size: %d\n"),
static_cast<int>(mapspec.entrysize));
// TGA image spec // TGA image spec
@@ -179,20 +190,47 @@ print_tga_info(BFile &file)
imagespec.depth = buf[16]; imagespec.depth = buf[16];
imagespec.descriptor = buf[17]; imagespec.descriptor = buf[17];
printf("\nImage Spec:\n"); printf(B_TRANSLATE("\nImage Spec:\n"));
printf(" x origin: %d\n", imagespec.xorigin); printf(B_TRANSLATE(" x origin: %d\n"),
printf(" y origin: %d\n", imagespec.yorigin); static_cast<int>(imagespec.xorigin));
printf(" width: %d\n", imagespec.width); printf(B_TRANSLATE(" y origin: %d\n"),
printf(" height: %d\n", imagespec.height); static_cast<int>(imagespec.yorigin));
printf(" depth: %d\n", imagespec.depth); printf(B_TRANSLATE(" width: %d\n"),
printf("descriptor: 0x%.2x\n", imagespec.descriptor); static_cast<int>(imagespec.width));
printf("\talpha (attr): %d\n", printf(B_TRANSLATE(" height: %d\n"),
imagespec.descriptor & TGA_DESC_ALPHABITS); static_cast<int>(imagespec.height));
printf("\t origin: %d (%s %s)\n", printf(B_TRANSLATE(" depth: %d\n"),
imagespec.descriptor & (TGA_ORIGIN_VERT_BIT | TGA_ORIGIN_HORZ_BIT), static_cast<int>(imagespec.depth));
((imagespec.descriptor & TGA_ORIGIN_VERT_BIT) ? "top" : "bottom"), printf(B_TRANSLATE("descriptor: 0x%.2x\n"),
((imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) ? "right" : "left")); static_cast<int>(imagespec.descriptor));
printf("\t bits 7 & 6: %d\n", imagespec.descriptor & TGA_DESC_BITS76); printf(B_TRANSLATE("\talpha (attr): %d\n"),
static_cast<int>(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<int>(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT
| TGA_ORIGIN_HORZ_BIT)), static_cast<const char *>("top"),
static_cast<const char *>("right"));
else
printf(B_TRANSLATE("\t origin: %d (%s %s)\n"),
static_cast<int>(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT
| TGA_ORIGIN_HORZ_BIT)), static_cast<const char *>("top"),
static_cast<const char *>("left"));
else
if (imagespec.descriptor & TGA_ORIGIN_HORZ_BIT)
printf(B_TRANSLATE("\t origin: %d (%s %s)\n"),
static_cast<int>(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT
| TGA_ORIGIN_HORZ_BIT)), static_cast<const char *>("bottom"),
static_cast<const char *>("right"));
else
printf(B_TRANSLATE("\t origin: %d (%s %s)\n"),
static_cast<int>(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT
| TGA_ORIGIN_HORZ_BIT)), static_cast<const char *>("bottom"),
static_cast<const char *>("left"));
printf(B_TRANSLATE("\t bits 7 & 6: %d\n"),
static_cast<int>(imagespec.descriptor & TGA_DESC_BITS76));
// Optional TGA Footer // Optional TGA Footer
@@ -208,107 +246,128 @@ print_tga_info(BFile &file)
extoffset = tga_uint32(tgafooter, 0); extoffset = tga_uint32(tgafooter, 0);
devoffset = tga_uint32(tgafooter, 4); devoffset = tga_uint32(tgafooter, 4);
printf("\nTGA Footer:\n"); printf(B_TRANSLATE("\nTGA Footer:\n"));
printf("extension offset: 0x%.8lx (%ld)\n", extoffset, extoffset); printf(B_TRANSLATE("extension offset: 0x%.8lx (%ld)\n"),
printf("developer offset: 0x%.8lx (%ld)\n", devoffset, devoffset); static_cast<long int>(extoffset),
printf("signature: %s\n", tgafooter + 8); static_cast<long int>(extoffset));
printf(B_TRANSLATE("developer offset: 0x%.8lx (%ld)\n"),
static_cast<long int>(devoffset),
static_cast<long int>(devoffset));
printf(B_TRANSLATE("signature: %s\n"), tgafooter + 8);
if (extoffset) { if (extoffset) {
char extbuf[TGA_EXT_LEN]; char extbuf[TGA_EXT_LEN];
if (file.ReadAt(extoffset, extbuf, TGA_EXT_LEN) == 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]; char strbuffer[LINE_LEN];
uint16 extsize = tga_uint16(extbuf, 0); uint16 extsize = tga_uint16(extbuf, 0);
if (extsize < TGA_EXT_LEN) { 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; return;
} }
printf("size: %d\n", extsize); printf(B_TRANSLATE("size: %d\n"), extsize);
memset(strbuffer, 0, LINE_LEN); memset(strbuffer, 0, LINE_LEN);
strncpy(strbuffer, extbuf + 2, 41); strncpy(strbuffer, extbuf + 2, 41);
printf("author: \"%s\"\n", strbuffer); printf("author: \"%s\"\n", strbuffer);
printf("comments:\n"); printf(B_TRANSLATE("comments:\n"));
for (int32 i = 0; i < 4; i++) { for (int32 i = 0; i < 4; i++) {
memset(strbuffer, 0, LINE_LEN); memset(strbuffer, 0, LINE_LEN);
strcpy(strbuffer, extbuf + 43 + (i * 81)); strcpy(strbuffer, extbuf + 43 + (i * 81));
printf("\tline %ld: \"%s\"\n", i + 1, strbuffer); printf(B_TRANSLATE("\tline %ld: \"%s\"\n"),
static_cast<long int>(i + 1),
static_cast<const char *>(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, 367), tga_uint16(extbuf, 369),
tga_uint16(extbuf, 371), tga_uint16(extbuf, 373), tga_uint16(extbuf, 371), tga_uint16(extbuf, 373),
tga_uint16(extbuf, 375), tga_uint16(extbuf, 377)); tga_uint16(extbuf, 375), tga_uint16(extbuf, 377));
memset(strbuffer, 0, LINE_LEN); memset(strbuffer, 0, LINE_LEN);
strncpy(strbuffer, extbuf + 379, 41); 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", printf(B_TRANSLATE("job time (hh:mm:ss): "
tga_uint16(extbuf, 420), tga_uint16(extbuf, 422), "%.2d:%.2d:%.2d\n"), tga_uint16(extbuf, 420),
tga_uint16(extbuf, 424)); tga_uint16(extbuf, 422), tga_uint16(extbuf, 424));
memset(strbuffer, 0, LINE_LEN); memset(strbuffer, 0, LINE_LEN);
strncpy(strbuffer, extbuf + 426, 41); strncpy(strbuffer, extbuf + 426, 41);
printf("software id: \"%s\"\n", strbuffer); printf(B_TRANSLATE("software id: \"%s\"\n"),
strbuffer);
char strver[] = "[null]"; char strver[] = "[null]";
if (extbuf[469] != '\0') { if (extbuf[469] != '\0') {
strver[0] = extbuf[469]; strver[0] = extbuf[469];
strver[1] = '\0'; strver[1] = '\0';
} }
printf("software version, letter: %d, %s\n", printf(B_TRANSLATE("software version, letter: %d, "
tga_uint16(extbuf, 467), strver); "%s\n"), tga_uint16(extbuf, 467), strver);
printf("key color (A,R,G,B): %d, %d, %d, %d\n", printf(B_TRANSLATE("key color (A,R,G,B): %d, %d, %d, "
extbuf[470], extbuf[471], extbuf[472], extbuf[473]); "%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)); 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)); tga_uint16(extbuf, 478), tga_uint16(extbuf, 480));
printf("color correction offset: 0x%.8lx (%ld)\n", printf(B_TRANSLATE("color correction offset: 0x%.8lx "
tga_uint32(extbuf, 482), tga_uint32(extbuf, 482)); "(%ld)\n"), tga_uint32(extbuf, 482),
printf("postage stamp offset: 0x%.8lx (%ld)\n", tga_uint32(extbuf, 482));
tga_uint32(extbuf, 486), tga_uint32(extbuf, 486)); printf(B_TRANSLATE("postage stamp offset: 0x%.8lx "
printf("scan line offset: 0x%.8lx (%ld)\n", "(%ld)\n"), tga_uint32(extbuf, 486),
tga_uint32(extbuf, 490), tga_uint32(extbuf, 490)); 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; const char *strattrtype = NULL;
uint8 attrtype = extbuf[494]; uint8 attrtype = extbuf[494];
switch (attrtype) { switch (attrtype) {
case 0: strattrtype = "no alpha"; break; case 0: strattrtype
case 1: strattrtype = "undefined, ignore"; break; = B_TRANSLATE("no alpha"); break;
case 2: strattrtype = "undefined, retain"; break; case 1: strattrtype
case 3: strattrtype = "alpha"; break; = B_TRANSLATE("undefined, ignore"); break;
case 4: strattrtype = "pre-multiplied alpha"; 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: default:
if (attrtype > 4 && attrtype < 128) if (attrtype > 4 && attrtype < 128)
strattrtype = "reserved"; strattrtype = B_TRANSLATE("reserved");
else else
strattrtype = "unassigned"; strattrtype = B_TRANSLATE("unassigned");
break; break;
} }
printf("attributes type: %d (%s)\n", attrtype, strattrtype); printf(B_TRANSLATE("attributes type: %d (%s)\n"),
attrtype, strattrtype);
} else } else
printf("\nError: Unable to read entire extension area\n"); printf(B_TRANSLATE("\nError: Unable to read entire "
"extension area\n"));
} }
} else } else
printf("\nTGA footer not found\n"); printf(B_TRANSLATE("\nTGA footer not found\n"));
} else } else
printf("\nError: Unable to read TGA footer section\n"); printf(B_TRANSLATE("\nError: Unable to read TGA footer "
"section\n"));
} else } else
printf("\nError: Unable to get file size\n"); printf(B_TRANSLATE("\nError: Unable to get file size\n"));
} }
int int
@@ -317,18 +376,18 @@ main(int argc, char **argv)
printf("\n"); printf("\n");
if (argc == 1) { if (argc == 1) {
printf("tgainfo - reports information about a TGA image file\n"); printf(B_TRANSLATE("tgainfo - reports information about a TGA image file\n"));
printf("\nUsage:\n"); printf(B_TRANSLATE("\nUsage:\n"));
printf("tgainfo filename.tga\n"); printf(B_TRANSLATE("tgainfo filename.tga\n"));
} }
else { else {
BFile file; BFile file;
for (int32 i = 1; i < argc; i++) { for (int32 i = 1; i < argc; i++) {
if (file.SetTo(argv[i], B_READ_ONLY) != B_OK) 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 { 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); print_tga_info(file);
} }
} }
@@ -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;