Merge branch 'master' into sam460ex
This commit is contained in:
commit
228524afb6
@ -98,11 +98,11 @@ SYSTEM_NETWORK_PROTOCOLS = ipv4 tcp udp icmp unix icmp6 ipv6 ;
|
||||
|
||||
SYSTEM_ADD_ONS_ACCELERANTS = [ FFilterByBuildFeatures
|
||||
x86,x86_64 @{
|
||||
vesa.accelerant
|
||||
vesa.accelerant intel_extreme.accelerant
|
||||
}@ # x86,x86_64
|
||||
x86 @{
|
||||
3dfx.accelerant ati.accelerant matrox.accelerant neomagic.accelerant
|
||||
nvidia.accelerant intel_810.accelerant intel_extreme.accelerant
|
||||
nvidia.accelerant intel_810.accelerant
|
||||
radeon.accelerant radeon_hd.accelerant s3.accelerant
|
||||
#via.accelerant vmware.accelerant
|
||||
}@ # x86
|
||||
@ -156,10 +156,10 @@ SYSTEM_ADD_ONS_DRIVERS_AUDIO = auich auvia echo3g emuxki hda ice1712 sis7018 ;
|
||||
SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD = ; #cmedia usb_audio ;
|
||||
SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = [ FFilterByBuildFeatures
|
||||
x86,x86_64 @{
|
||||
vesa
|
||||
vesa intel_extreme
|
||||
}@ # x86,x86_64
|
||||
x86 @{
|
||||
ati 3dfx intel_810 intel_extreme matrox neomagic nvidia radeon radeon_hd
|
||||
ati 3dfx intel_810 matrox neomagic nvidia radeon radeon_hd
|
||||
s3 #via vmware
|
||||
}@ # x86
|
||||
] ;
|
||||
@ -187,7 +187,7 @@ SYSTEM_ADD_ONS_DRIVERS_NET = [ FFilterByBuildFeatures
|
||||
SYSTEM_ADD_ONS_DRIVERS_POWER = [ FFilterByBuildFeatures acpi_button@x86 ] ;
|
||||
SYSTEM_ADD_ONS_BUS_MANAGERS = [ FFilterByBuildFeatures
|
||||
ata@ata pci ps2@x86,x86_64 isa@x86,x86_64
|
||||
ide@ide scsi config_manager agp_gart@x86 usb firewire@x86 acpi@x86
|
||||
ide@ide scsi config_manager agp_gart@x86,x86_64 usb firewire@x86 acpi@x86
|
||||
virtio random
|
||||
] ;
|
||||
SYSTEM_ADD_ONS_FILE_SYSTEMS = bfs btrfs cdda exfat ext2 fat iso9660 nfs nfs4
|
||||
@ -216,7 +216,7 @@ for driver in $(SYSTEM_ADD_ONS_DRIVERS_NET) {
|
||||
AddFilesToHaikuImage system add-ons kernel bus_managers
|
||||
: $(SYSTEM_ADD_ONS_BUS_MANAGERS) ;
|
||||
AddFilesToHaikuImage system add-ons kernel busses agp_gart
|
||||
: <agp_gart>intel@x86 ;
|
||||
: <agp_gart>intel@x86,x86_64 ;
|
||||
|
||||
if $(HAIKU_ATA_STACK) = 1 {
|
||||
AddFilesToHaikuImage system add-ons kernel busses ata
|
||||
|
@ -20,7 +20,7 @@ additionalMakeArgs=$*
|
||||
# additional flags for the binutils build. Should there ever be any other
|
||||
# flags than -jN, we need to handle this differently.
|
||||
|
||||
if [ `uname -o` = 'Haiku' ]; then
|
||||
if [ `uname -s` = 'Haiku' ]; then
|
||||
# force cross-build if building on Haiku:
|
||||
buildhostMachine=i586-pc-haiku_buildhost
|
||||
buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine"
|
||||
|
@ -50,7 +50,7 @@ arm-*)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ `uname -o` = 'Haiku' ]; then
|
||||
if [ `uname -s` = 'Haiku' ]; then
|
||||
# force cross-build if building on Haiku:
|
||||
buildhostMachine=${haikuMachine}_buildhost
|
||||
buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine"
|
||||
|
@ -1,4 +1,4 @@
|
||||
1 finnish x-vnd.Haiku-ActivityMonitor 2739021859
|
||||
1 finnish x-vnd.Haiku-ActivityMonitor 1211510241
|
||||
P-faults DataSource P-viat
|
||||
Media nodes DataSource Mediasolmut
|
||||
Threads DataSource Säikeet
|
||||
@ -6,6 +6,7 @@ Always on top ActivityWindow Aina päällimmäisenä
|
||||
Add graph ActivityWindow Lisää kuvaaja
|
||||
Teams DataSource Ryhmät
|
||||
Hide legend ActivityView Piilota merkin selitys
|
||||
MiB DataSource mebitavua
|
||||
Network send DataSource Verkkolähetys
|
||||
CPU usage (combined) DataSource Suoritinkäyttö (yhdistetty)
|
||||
CPU DataSource Suoritin
|
||||
@ -26,12 +27,14 @@ Update time interval: SettingsWindow Päivitä aikaväli:
|
||||
TX DataSource Shorter version for Sending Läh.
|
||||
Quit ActivityWindow Poistu
|
||||
Block cache memory DataSource Lohkovälimuisti
|
||||
%.1f KiB/s DataSource %.1f kibitavua/s
|
||||
Remove graph ActivityView Poista kuvaaja
|
||||
%lld sec. SettingsWindow %lld s
|
||||
%lld ms SettingsWindow %lld ms
|
||||
CPU usage DataSource Suoritinkäyttö
|
||||
Raw clipboard DataSource Raakadataleikepöytä
|
||||
Sems DataSource Opastimet
|
||||
%.1f MiB DataSource %.1f Mebitavua
|
||||
ActivityMonitor System name Aktiviteettivalvonta
|
||||
Running applications DataSource Suoritetaan sovelluksia
|
||||
Semaphores DataSource Opastimet
|
||||
|
@ -1,4 +1,4 @@
|
||||
1 french x-vnd.haiku-icon_o_matic 605140404
|
||||
1 french x-vnd.haiku-icon_o_matic 806315965
|
||||
Select All Icon-O-Matic-PathManipulator Sélectionner tout
|
||||
Add Style Icon-O-Matic-AddStylesCmd Ajouter un style
|
||||
Color (#%02x%02x%02x) Style name after dropping a color Couleur (#%02x%02x%02x)
|
||||
@ -67,6 +67,7 @@ Contour Transformation Contour
|
||||
Perspective Transformation Perspective
|
||||
Move Transformer Icon-O-Matic-MoveTransformersCmd Déplacer la Transformation
|
||||
Opacity Icon-O-Matic-PropertyNames Opacité
|
||||
Add with path Icon-O-Matic-ShapesList Ajouter avec un chemin
|
||||
Gradient type Icon-O-Matic-StyleTypes Type de dégradé
|
||||
Icon-O-Matic System name Icon-O-Matic
|
||||
Cancel Icon-O-Matic-Menu-Settings Annuler
|
||||
@ -79,6 +80,7 @@ META:ICON Attribute Icon-O-Matic-SavePanel Attribut META:ICON
|
||||
Translation Y Icon-O-Matic-PropertyNames Translation en Y
|
||||
Rotate Icon-O-Matic-TransformationBoxStates Pivoter
|
||||
Remove Transformer Icon-O-Matic-RemoveTransformersCmd Supprimer une transformation
|
||||
Rotate Path Indices Icon-O-Matic-RotatePathIndiciesCmd Rotation des indices de chemin
|
||||
Add Transformer Icon-O-Matic-AddTransformersCmd Ajouter une transformation
|
||||
Remove Icon-O-Matic-PathsList Enlever
|
||||
Nudge Control Point Icon-O-Matic-NudgePointsCommand Déplacer le point de contrôle
|
||||
|
@ -1,7 +1,8 @@
|
||||
1 finnish x-vnd.Haiku-libmail 161731481
|
||||
1 finnish x-vnd.Haiku-libmail 4037525365
|
||||
Partially download messages larger than ProtocolConfigView Osittain ladatut viestit suurempia kuin
|
||||
Password: ProtocolConfigView Salasana:
|
||||
Remove mail from server when deleted ProtocolConfigView Poista sähköposti palvelimelta poistettaessa
|
||||
KiB ProtocolConfigView kibitavua
|
||||
Mail server: ProtocolConfigView Sähköpostipalvelin:
|
||||
Select… MailKit Valitse...
|
||||
Connection type: ProtocolConfigView Yhteystyyppi:
|
||||
|
@ -1,4 +1,4 @@
|
||||
1 belarusian x-vnd.Haiku-ScreenSaver 3630119516
|
||||
1 belarusian x-vnd.Haiku-ScreenSaver 232492478
|
||||
Could not load screen saver ScreenSaver Не ўдалося загрузіць захавальнік экрана
|
||||
30 seconds ScreenSaver 30 секунд
|
||||
Start screensaver ScreenSaver Запусціць захавальнік
|
||||
@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Кіраванне
|
||||
ScreenSaver System name Захавальнік Экрана
|
||||
Test ScreenSaver Тэст
|
||||
General ScreenSaver Агульныя
|
||||
Fade now when mouse is here ScreenSaver Зацямняць перасунуўшы указальнік мышы сюды
|
||||
Enable screensaver ScreenSaver Уключыць захавальнік
|
||||
Don't fade when mouse is here ScreenSaver Не зацямняць калі указальнік мышы знаходзіцца тут
|
||||
Cancel ScreenSaver Адмена
|
||||
Turn off screen ScreenSaver Выключыць экран
|
||||
No options available ScreenSaver Ніякія опцыі недаступныя
|
||||
|
@ -1,4 +1,4 @@
|
||||
1 german x-vnd.Haiku-ScreenSaver 3630119516
|
||||
1 german x-vnd.Haiku-ScreenSaver 232492478
|
||||
Could not load screen saver ScreenSaver Bildschirmschoner konnte nicht geladen werden.
|
||||
30 seconds ScreenSaver 30 Sekunden
|
||||
Start screensaver ScreenSaver Bildschirmschoner starten
|
||||
@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Stromsparfunktione
|
||||
ScreenSaver System name Bildschirmschoner
|
||||
Test ScreenSaver Test
|
||||
General ScreenSaver Allgemein
|
||||
Fade now when mouse is here ScreenSaver Sofort starten, wenn Maus in diesem Eck
|
||||
Enable screensaver ScreenSaver Bildschirmschoner aktivieren
|
||||
Don't fade when mouse is here ScreenSaver Nicht starten, wenn Maus in diesem Eck
|
||||
Cancel ScreenSaver Abbrechen
|
||||
Turn off screen ScreenSaver Bildschirm ausschalten
|
||||
No options available ScreenSaver Keine Optionen verfügbar
|
||||
|
@ -1,4 +1,4 @@
|
||||
1 finnish x-vnd.Haiku-ScreenSaver 3630119516
|
||||
1 finnish x-vnd.Haiku-ScreenSaver 232492478
|
||||
Could not load screen saver ScreenSaver Näytönsäästäjän lataus epäonnistui
|
||||
30 seconds ScreenSaver 30 sekuntia
|
||||
Start screensaver ScreenSaver Käynnistä näytönsäästäjä
|
||||
@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Näytön jännites
|
||||
ScreenSaver System name Näytönsäästäjäasetukset
|
||||
Test ScreenSaver Testaa
|
||||
General ScreenSaver Yleinen
|
||||
Fade now when mouse is here ScreenSaver Häivytä nyt kun hiiren kohdistin on tässä
|
||||
Enable screensaver ScreenSaver Ota käyttöön näytönsäästäjä
|
||||
Don't fade when mouse is here ScreenSaver Älä häivytä, kun hiiren kohdistin on tässä
|
||||
Cancel ScreenSaver Peru
|
||||
Turn off screen ScreenSaver Käännä näyttö pois päältä
|
||||
No options available ScreenSaver Valitsimia ei ole käytettävissä
|
||||
|
@ -1,4 +1,4 @@
|
||||
1 french x-vnd.Haiku-ScreenSaver 3630119516
|
||||
1 french x-vnd.Haiku-ScreenSaver 232492478
|
||||
Could not load screen saver ScreenSaver Impossible de charger l'économiseur d'écran
|
||||
30 seconds ScreenSaver 30 secondes
|
||||
Start screensaver ScreenSaver Démarrer l'économiseur
|
||||
@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Le système d'éco
|
||||
ScreenSaver System name Économiseur d'écran
|
||||
Test ScreenSaver Tester
|
||||
General ScreenSaver Général
|
||||
Fade now when mouse is here ScreenSaver Estomper maintenant lorsque la souris est ici
|
||||
Enable screensaver ScreenSaver Activer l'économiseur
|
||||
Don't fade when mouse is here ScreenSaver Ne pas estomper lorsque la souris est ici
|
||||
Cancel ScreenSaver Annuler
|
||||
Turn off screen ScreenSaver Extinction de l'écran
|
||||
No options available ScreenSaver Aucune option disponible
|
||||
|
@ -1,4 +1,4 @@
|
||||
1 hungarian x-vnd.Haiku-ScreenSaver 3630119516
|
||||
1 hungarian x-vnd.Haiku-ScreenSaver 232492478
|
||||
Could not load screen saver ScreenSaver A képernyővédő betöltése sikertelen
|
||||
30 seconds ScreenSaver 30 másodperc
|
||||
Start screensaver ScreenSaver Képernyővédő indítása
|
||||
@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver A kijelző energia
|
||||
ScreenSaver System name Képernyővédő
|
||||
Test ScreenSaver Próba
|
||||
General ScreenSaver Általános
|
||||
Fade now when mouse is here ScreenSaver Bekapcsolás, ha az egér itt van
|
||||
Enable screensaver ScreenSaver Képernyővédő engedélyezése
|
||||
Don't fade when mouse is here ScreenSaver Ne kapcsoljon be, ha az egér itt van
|
||||
Cancel ScreenSaver Mégse
|
||||
Turn off screen ScreenSaver Képernyő kikapcsolása
|
||||
No options available ScreenSaver Nincsenek elérhető beállítások
|
||||
|
@ -1,4 +1,4 @@
|
||||
1 japanese x-vnd.Haiku-ScreenSaver 3630119516
|
||||
1 japanese x-vnd.Haiku-ScreenSaver 232492478
|
||||
Could not load screen saver ScreenSaver スクリーンセーバーを実行できませんでした
|
||||
30 seconds ScreenSaver 30 秒
|
||||
Start screensaver ScreenSaver スクリーンセーバーを開始
|
||||
@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver DPMS (Display Powe
|
||||
ScreenSaver System name スクリーンセーバー
|
||||
Test ScreenSaver テスト
|
||||
General ScreenSaver 一般
|
||||
Fade now when mouse is here ScreenSaver マウスが指定の場所にあるときに画面を消す
|
||||
Enable screensaver ScreenSaver スクリーンセーバーを有効にする
|
||||
Don't fade when mouse is here ScreenSaver マウスが指定の場所にあるとき画面を消さない
|
||||
Cancel ScreenSaver 取り消し
|
||||
Turn off screen ScreenSaver 画面を消す
|
||||
No options available ScreenSaver 設定がありません
|
||||
|
@ -1,3 +1,8 @@
|
||||
* Determine how to handle atomic functions on ARM.
|
||||
GCC inlines are not supported, since the instructionset is ill-equiped for
|
||||
this on older (pre-ARMv7) architectures. We possibly have to do something
|
||||
similar to the linux kernel helper functions for this....
|
||||
|
||||
* Figure out how to get page flags (modified/accessed) and implement it ;)
|
||||
use unmapped/read-only mappings to trigger soft faults
|
||||
for tracking used/modified flags for ARMv5 and ARMv6
|
||||
|
@ -43,7 +43,7 @@
|
||||
#define PATH_MAX (1024)
|
||||
#define PIPE_MAX (512)
|
||||
#define PTHREAD_KEYS_MAX 256
|
||||
#define PTHREAD_STACK_MIN 4096
|
||||
#define PTHREAD_STACK_MIN (2 * PAGE_SIZE)
|
||||
#define SSIZE_MAX __HAIKU_SADDR_MAX
|
||||
#define TTY_NAME_MAX (256)
|
||||
#define TZNAME_MAX (32)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#define IFM_100_TX 6 /* 100Base-TX - RJ45 */
|
||||
#define IFM_1000_T 16 /* 1000Base-T - RJ45 */
|
||||
#define IFM_1000_SX 18 /* 1000Base-SX - Fiber Optic */
|
||||
#define IFM_10G_T 22 /* 10GBase-T - RJ45 */
|
||||
|
||||
/* General options */
|
||||
|
||||
|
@ -135,6 +135,8 @@ public:
|
||||
bool IsExpanded() const;
|
||||
bool IsSelected() const;
|
||||
|
||||
void Invalidate();
|
||||
|
||||
private:
|
||||
// Blows up into the debugger if the validation fails.
|
||||
void ValidateFields() const;
|
||||
@ -332,6 +334,8 @@ public:
|
||||
parentRow1 = NULL, BRow* parentRow2 = NULL);
|
||||
void Clear();
|
||||
|
||||
void InvalidateRow(BRow* row);
|
||||
|
||||
// Appearance (DEPRECATED)
|
||||
void GetFont(BFont* font) const
|
||||
{ BView::GetFont(font); }
|
||||
|
@ -13,10 +13,10 @@
|
||||
|
||||
/** Size of the stack given to teams in user space */
|
||||
#define USER_STACK_GUARD_SIZE (4 * B_PAGE_SIZE) // 16 kB
|
||||
#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB
|
||||
#define USER_STACK_SIZE (256 * 1024) // 256 kB
|
||||
#define MIN_USER_STACK_SIZE (8 * 1024) // 8 kB
|
||||
#define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB
|
||||
#define MIN_USER_STACK_SIZE (2 * B_PAGE_SIZE) // 8 kB
|
||||
#define MAX_USER_STACK_SIZE (4096 * B_PAGE_SIZE) // 16 MB
|
||||
#define USER_MAIN_THREAD_STACK_SIZE MAX_USER_STACK_SIZE
|
||||
#define USER_STACK_SIZE (64 * B_PAGE_SIZE) // 256 kB
|
||||
|
||||
|
||||
// The type of object a thread blocks on (thread::wait::type, set by
|
||||
|
@ -141,9 +141,11 @@ init_common(int device, bool isClone)
|
||||
// The overlay registers, hardware status, and cursor memory share
|
||||
// a single area with the shared_info
|
||||
|
||||
gInfo->overlay_registers = (struct overlay_registers*)
|
||||
(gInfo->shared_info->graphics_memory
|
||||
+ gInfo->shared_info->overlay_offset);
|
||||
if (gInfo->shared_info->overlay_offset != 0) {
|
||||
gInfo->overlay_registers = (struct overlay_registers*)
|
||||
(gInfo->shared_info->graphics_memory
|
||||
+ gInfo->shared_info->overlay_offset);
|
||||
}
|
||||
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_96x)) {
|
||||
// allocate some extra memory for the 3D context
|
||||
|
@ -431,7 +431,10 @@ retrieve_current_mode(display_mode& mode, uint32 pllRegister)
|
||||
mode.h_display_start = 0;
|
||||
mode.v_display_start = 0;
|
||||
mode.flags = B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS
|
||||
| B_DPMS | B_SUPPORTS_OVERLAYS;
|
||||
| B_DPMS;
|
||||
if (gInfo->overlay_registers != NULL) {
|
||||
mode.flags |= B_SUPPORTS_OVERLAYS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1174,6 +1174,57 @@ hda_codec_switch_init(hda_audio_group* audioGroup)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hda_codec_check_sense(hda_codec* codec, bool disable)
|
||||
{
|
||||
hda_audio_group* audioGroup = codec->audio_groups[0];
|
||||
|
||||
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
|
||||
hda_widget& widget = audioGroup->widgets[i];
|
||||
|
||||
if (widget.type != WT_PIN_COMPLEX
|
||||
|| !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities)
|
||||
|| CONF_DEFAULT_DEVICE(widget.d.pin.config)
|
||||
!= PIN_DEV_HEAD_PHONE_OUT)
|
||||
continue;
|
||||
|
||||
corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id,
|
||||
VID_GET_PINSENSE, 0);
|
||||
uint32 response;
|
||||
hda_send_verbs(audioGroup->codec, &verb, &response, 1);
|
||||
disable = response & PIN_SENSE_PRESENCE_DETECT;
|
||||
TRACE("hda: sensed pin widget %ld, %d\n", widget.node_id, disable);
|
||||
|
||||
uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget,
|
||||
true);
|
||||
verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id,
|
||||
VID_SET_PIN_WIDGET_CONTROL, disable ? ctrl : 0);
|
||||
hda_send_verbs(audioGroup->codec, &verb, NULL, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
|
||||
hda_widget& widget = audioGroup->widgets[i];
|
||||
|
||||
if (widget.type != WT_PIN_COMPLEX
|
||||
|| !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities))
|
||||
continue;
|
||||
|
||||
int device = CONF_DEFAULT_DEVICE(widget.d.pin.config);
|
||||
if (device != PIN_DEV_AUX
|
||||
&& device != PIN_DEV_SPEAKER
|
||||
&& device != PIN_DEV_LINE_OUT)
|
||||
continue;
|
||||
|
||||
uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget,
|
||||
true);
|
||||
corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id,
|
||||
VID_SET_PIN_WIDGET_CONTROL, disable ? 0 : ctrl);
|
||||
hda_send_verbs(audioGroup->codec, &verb, NULL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
hda_codec_switch_handler(hda_codec* codec)
|
||||
{
|
||||
@ -1182,53 +1233,8 @@ hda_codec_switch_handler(hda_codec* codec)
|
||||
codec->unsol_response_read %= MAX_CODEC_UNSOL_RESPONSES;
|
||||
|
||||
bool disable = response & 1;
|
||||
hda_audio_group* audioGroup = codec->audio_groups[0];
|
||||
|
||||
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
|
||||
hda_widget& widget = audioGroup->widgets[i];
|
||||
|
||||
if (widget.type != WT_PIN_COMPLEX
|
||||
|| !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities)
|
||||
|| CONF_DEFAULT_DEVICE(widget.d.pin.config)
|
||||
!= PIN_DEV_HEAD_PHONE_OUT)
|
||||
continue;
|
||||
|
||||
corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id,
|
||||
VID_GET_PINSENSE, 0);
|
||||
uint32 response;
|
||||
hda_send_verbs(audioGroup->codec, &verb, &response, 1);
|
||||
disable = response & PIN_SENSE_PRESENCE_DETECT;
|
||||
TRACE("hda: sensed pin widget %ld, %d\n", widget.node_id, disable);
|
||||
|
||||
uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget,
|
||||
true);
|
||||
verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id,
|
||||
VID_SET_PIN_WIDGET_CONTROL, disable ? ctrl : 0);
|
||||
hda_send_verbs(audioGroup->codec, &verb, NULL, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
|
||||
hda_widget& widget = audioGroup->widgets[i];
|
||||
|
||||
if (widget.type != WT_PIN_COMPLEX
|
||||
|| !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities))
|
||||
continue;
|
||||
|
||||
int device = CONF_DEFAULT_DEVICE(widget.d.pin.config);
|
||||
if (device != PIN_DEV_AUX
|
||||
&& device != PIN_DEV_SPEAKER
|
||||
&& device != PIN_DEV_LINE_OUT)
|
||||
continue;
|
||||
|
||||
uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget,
|
||||
true);
|
||||
corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id,
|
||||
VID_SET_PIN_WIDGET_CONTROL, disable ? 0 : ctrl);
|
||||
hda_send_verbs(audioGroup->codec, &verb, NULL, 1);
|
||||
}
|
||||
hda_codec_check_sense(codec, disable);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -1521,6 +1527,8 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
|
||||
}
|
||||
}
|
||||
|
||||
hda_codec_check_sense(codec, false);
|
||||
|
||||
codec->unsol_response_thread = spawn_kernel_thread(
|
||||
(status_t(*)(void*))hda_codec_switch_handler,
|
||||
"hda_codec_unsol_thread", B_LOW_PRIORITY, codec);
|
||||
|
@ -31,7 +31,10 @@
|
||||
|
||||
|
||||
#define NORFLASH_ADDR 0x00000000
|
||||
#define SIZE_IN_BLOCKS 256
|
||||
|
||||
/* Hide the start of NOR since U-Boot lives there */
|
||||
#define HIDDEN_BLOCKS 2
|
||||
|
||||
struct nor_driver_info {
|
||||
device_node *node;
|
||||
@ -54,7 +57,7 @@ nor_init_device(void *_info, void **_cookie)
|
||||
|
||||
info->mapped = NULL;
|
||||
info->blocksize = 128 * 1024;
|
||||
info->totalsize = info->blocksize * 256;
|
||||
info->totalsize = (SIZE_IN_BLOCKS - HIDDEN_BLOCKS) * info->blocksize;
|
||||
|
||||
info->id = map_physical_memory("NORFlash", NORFLASH_ADDR, info->totalsize, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &info->mapped);
|
||||
if (info->id < 0)
|
||||
@ -139,6 +142,8 @@ nor_read(void *_cookie, off_t position, void *data, size_t *numbytes)
|
||||
nor_driver_info *info = (nor_driver_info*)_cookie;
|
||||
TRACE("read(%Ld,%lu)\n", position, *numbytes);
|
||||
|
||||
position += HIDDEN_BLOCKS * info->blocksize;
|
||||
|
||||
if (position + *numbytes > info->totalsize)
|
||||
*numbytes = info->totalsize - (position + *numbytes);
|
||||
|
||||
@ -160,8 +165,16 @@ nor_write(void *_cookie, off_t position, const void *data, size_t *numbytes)
|
||||
static float
|
||||
nor_supports_device(device_node *parent)
|
||||
{
|
||||
const char *bus;
|
||||
TRACE("supports_device\n");
|
||||
return 0.6;
|
||||
|
||||
if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
|
||||
return B_ERROR;
|
||||
|
||||
if (strcmp(bus, "generic"))
|
||||
return 0.0;
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -267,8 +267,8 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength,
|
||||
uint32 logicalBlockAddress, uint16 transferLength, void *data,
|
||||
size_t *dataLength, bool directionIn)
|
||||
{
|
||||
TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %lu; tlen: %u; data: "
|
||||
"%p; dlen: %p (%lu); in: %c\n",
|
||||
TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %" B_PRIu32
|
||||
"; tlen: %u; data: %p; dlen: %p (%lu); in: %c\n",
|
||||
lun->logical_unit_number, operation, opLength, logicalBlockAddress,
|
||||
transferLength, data, dataLength, dataLength ? *dataLength : 0,
|
||||
directionIn ? 'y' : 'n');
|
||||
@ -487,7 +487,7 @@ usb_disk_request_sense(device_lun *lun)
|
||||
parameter.additional_sense_code_qualifier);
|
||||
lun->media_present = false;
|
||||
usb_disk_reset_capacity(lun);
|
||||
return B_DEV_NO_MEDIA;
|
||||
return B_DEV_NOT_READY;
|
||||
|
||||
case SCSI_SENSE_KEY_DATA_PROTECT:
|
||||
TRACE_ALWAYS("request_sense: write protected\n");
|
||||
@ -691,7 +691,7 @@ usb_disk_callback(void *cookie, status_t status, void *data,
|
||||
static status_t
|
||||
usb_disk_device_added(usb_device newDevice, void **cookie)
|
||||
{
|
||||
TRACE("device_added(0x%08lx)\n", newDevice);
|
||||
TRACE("device_added(0x%08" B_PRIx32 ")\n", newDevice);
|
||||
disk_device *device = (disk_device *)malloc(sizeof(disk_device));
|
||||
device->device = newDevice;
|
||||
device->removed = false;
|
||||
@ -856,7 +856,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
|
||||
sprintf(device->luns[i]->name, DEVICE_NAME, device->device_number, i);
|
||||
mutex_unlock(&gDeviceListLock);
|
||||
|
||||
TRACE("new device: 0x%08lx\n", (uint32)device);
|
||||
TRACE("new device: 0x%p\n", device);
|
||||
*cookie = (void *)device;
|
||||
return B_OK;
|
||||
}
|
||||
@ -865,7 +865,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
|
||||
static status_t
|
||||
usb_disk_device_removed(void *cookie)
|
||||
{
|
||||
TRACE("device_removed(0x%08lx)\n", (uint32)cookie);
|
||||
TRACE("device_removed(0x%p)\n", cookie);
|
||||
disk_device *device = (disk_device *)cookie;
|
||||
|
||||
mutex_lock(&gDeviceListLock);
|
||||
@ -963,7 +963,7 @@ usb_disk_prepare_partial_buffer(device_lun *lun, off_t position, size_t length,
|
||||
return result;
|
||||
}
|
||||
|
||||
off_t offset = position - (blockPosition * lun->block_size);
|
||||
off_t offset = position - (off_t)blockPosition * lun->block_size;
|
||||
partialBuffer = (uint8 *)blockBuffer + offset;
|
||||
return B_OK;
|
||||
}
|
||||
@ -1096,7 +1096,8 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
||||
case B_GET_MEDIA_STATUS:
|
||||
{
|
||||
*(status_t *)buffer = usb_disk_test_unit_ready(lun);
|
||||
TRACE("B_GET_MEDIA_STATUS: 0x%08lx\n", *(status_t *)buffer);
|
||||
TRACE("B_GET_MEDIA_STATUS: 0x%08" B_PRIx32 "\n",
|
||||
*(status_t *)buffer);
|
||||
result = B_OK;
|
||||
break;
|
||||
}
|
||||
@ -1117,8 +1118,9 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
||||
geometry.removable = lun->removable;
|
||||
geometry.read_only = lun->write_protected;
|
||||
geometry.write_once = lun->device_type == B_WORM;
|
||||
TRACE("B_GET_GEOMETRY: %ld sectors at %ld bytes per sector\n",
|
||||
geometry.cylinder_count, geometry.bytes_per_sector);
|
||||
TRACE("B_GET_GEOMETRY: %" B_PRId32 " sectors at %" B_PRId32
|
||||
" bytes per sector\n", geometry.cylinder_count,
|
||||
geometry.bytes_per_sector);
|
||||
result = user_memcpy(buffer, &geometry, sizeof(device_geometry));
|
||||
break;
|
||||
}
|
||||
@ -1212,7 +1214,7 @@ usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length)
|
||||
if (buffer == NULL || length == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
TRACE("read(%lld, %ld)\n", position, *length);
|
||||
TRACE("read(%" B_PRIdOFF ", %ld)\n", position, *length);
|
||||
device_lun *lun = (device_lun *)cookie;
|
||||
disk_device *device = lun->device;
|
||||
mutex_lock(&device->lock);
|
||||
@ -1260,7 +1262,7 @@ usb_disk_write(void *cookie, off_t position, const void *buffer,
|
||||
if (buffer == NULL || length == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
TRACE("write(%lld, %ld)\n", position, *length);
|
||||
TRACE("write(%" B_PRIdOFF", %ld)\n", position, *length);
|
||||
device_lun *lun = (device_lun *)cookie;
|
||||
disk_device *device = lun->device;
|
||||
mutex_lock(&device->lock);
|
||||
|
@ -9,6 +9,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network usb_asix ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network usb_davicom ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network usb_ecm ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network via_rhine ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network virtio ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network vlance ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network wb840 ;
|
||||
|
||||
|
8
src/add-ons/kernel/drivers/network/virtio/Jamfile
Normal file
8
src/add-ons/kernel/drivers/network/virtio/Jamfile
Normal file
@ -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
|
||||
;
|
462
src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp
Normal file
462
src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp
Normal file
@ -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
|
||||
};
|
202
src/add-ons/kernel/drivers/network/virtio/virtio_net.h
Normal file
202
src/add-ons/kernel/drivers/network/virtio/virtio_net.h
Normal file
@ -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,8 +633,9 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
||||
inode->SetAccessTime(×pec);
|
||||
inode->SetCreationTime(×pec);
|
||||
inode->SetModificationTime(×pec);
|
||||
node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED);
|
||||
if (volume->HasExtentsFeature()
|
||||
if (parent != NULL)
|
||||
node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED);
|
||||
if (volume->HasExtentsFeature()
|
||||
&& (inode->IsDirectory() || inode->IsFile())) {
|
||||
node.SetFlag(EXT2_INODE_EXTENTS);
|
||||
ExtentStream stream(volume, &node.extent_stream, 0);
|
||||
@ -935,4 +936,3 @@ Inode::IncrementNumLinks(Transaction& transaction)
|
||||
fVolume->ActivateDirNLink(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,13 +141,13 @@ struct ext2_super_block {
|
||||
{
|
||||
free_blocks = B_HOST_TO_LENDIAN_INT32(freeBlocks & 0xffffffff);
|
||||
if (has64bits)
|
||||
free_blocks_high = B_HOST_TO_LENDIAN_INT32(freeBlocks >> 32);
|
||||
free_blocks_high = B_HOST_TO_LENDIAN_INT32(freeBlocks >> 32);
|
||||
}
|
||||
void SetLastOrphan(ino_t id)
|
||||
{ last_orphan = B_HOST_TO_LENDIAN_INT32((uint32)id); }
|
||||
void SetReadOnlyFeatures(uint32 readOnlyFeatures) const
|
||||
{ readOnlyFeatures = B_HOST_TO_LENDIAN_INT32(readOnlyFeatures); }
|
||||
|
||||
|
||||
bool IsValid();
|
||||
// implemented in Volume.cpp
|
||||
} _PACKED;
|
||||
@ -211,7 +211,7 @@ struct ext2_block_group {
|
||||
uint32 _reserved[2];
|
||||
uint16 unused_inodes;
|
||||
uint16 checksum;
|
||||
|
||||
|
||||
// ext4
|
||||
uint32 block_bitmap_high;
|
||||
uint32 inode_bitmap_high;
|
||||
@ -249,7 +249,7 @@ struct ext2_block_group {
|
||||
{
|
||||
uint32 blocks = B_LENDIAN_TO_HOST_INT16(free_blocks);
|
||||
if (has64bits)
|
||||
blocks |=
|
||||
blocks |=
|
||||
((uint32)B_LENDIAN_TO_HOST_INT16(free_blocks_high) << 16);
|
||||
return blocks;
|
||||
}
|
||||
@ -257,7 +257,7 @@ struct ext2_block_group {
|
||||
{
|
||||
uint32 inodes = B_LENDIAN_TO_HOST_INT16(free_inodes);
|
||||
if (has64bits)
|
||||
inodes |=
|
||||
inodes |=
|
||||
((uint32)B_LENDIAN_TO_HOST_INT16(free_inodes_high) << 16);
|
||||
return inodes;
|
||||
}
|
||||
@ -265,7 +265,7 @@ struct ext2_block_group {
|
||||
{
|
||||
uint32 dirs = B_LENDIAN_TO_HOST_INT16(used_directories);
|
||||
if (has64bits)
|
||||
dirs |=
|
||||
dirs |=
|
||||
((uint32)B_LENDIAN_TO_HOST_INT16(used_directories_high) << 16);
|
||||
return dirs;
|
||||
}
|
||||
@ -274,11 +274,11 @@ struct ext2_block_group {
|
||||
{
|
||||
uint32 inodes = B_LENDIAN_TO_HOST_INT16(unused_inodes);
|
||||
if (has64bits)
|
||||
inodes |=
|
||||
inodes |=
|
||||
((uint32)B_LENDIAN_TO_HOST_INT16(unused_inodes_high) << 16);
|
||||
return inodes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SetFreeBlocks(uint32 freeBlocks, bool has64bits)
|
||||
{
|
||||
@ -376,7 +376,7 @@ struct ext2_extent_entry {
|
||||
uint32 physical_block;
|
||||
uint32 LogicalBlock() const
|
||||
{ return B_LENDIAN_TO_HOST_INT32(logical_block); }
|
||||
uint16 Length() const { return B_LENDIAN_TO_HOST_INT16(length) == 0x8000
|
||||
uint16 Length() const { return B_LENDIAN_TO_HOST_INT16(length) == 0x8000
|
||||
? 0x8000 : B_LENDIAN_TO_HOST_INT16(length) & 0x7fff; }
|
||||
uint64 PhysicalBlock() const { return B_LENDIAN_TO_HOST_INT32(physical_block)
|
||||
| ((uint64)B_LENDIAN_TO_HOST_INT16(physical_block_high) << 32); }
|
||||
@ -437,7 +437,7 @@ struct ext2_inode {
|
||||
uint16 uid_high;
|
||||
uint16 gid_high;
|
||||
uint32 _reserved2;
|
||||
|
||||
|
||||
// extra attributes
|
||||
uint16 extra_inode_size;
|
||||
uint16 _padding2;
|
||||
@ -460,18 +460,18 @@ struct ext2_inode {
|
||||
{
|
||||
timespec->tv_sec = B_LENDIAN_TO_HOST_INT32(time);
|
||||
if (extra && sizeof(timespec->tv_sec) > 4)
|
||||
timespec->tv_sec |=
|
||||
timespec->tv_sec |=
|
||||
(uint64)(B_LENDIAN_TO_HOST_INT32(time_extra) & 0x2) << 32;
|
||||
if (extra)
|
||||
timespec->tv_nsec = B_LENDIAN_TO_HOST_INT32(time_extra) >> 2;
|
||||
else
|
||||
timespec->tv_nsec = 0;
|
||||
}
|
||||
|
||||
void GetModificationTime(struct timespec *timespec, bool extra) const
|
||||
{ _DecodeTime(timespec, modification_time, modification_time_extra,
|
||||
|
||||
void GetModificationTime(struct timespec *timespec, bool extra) const
|
||||
{ _DecodeTime(timespec, modification_time, modification_time_extra,
|
||||
extra); }
|
||||
void GetAccessTime(struct timespec *timespec, bool extra) const
|
||||
void GetAccessTime(struct timespec *timespec, bool extra) const
|
||||
{ _DecodeTime(timespec, access_time, access_time_extra, extra); }
|
||||
void GetChangeTime(struct timespec *timespec, bool extra) const
|
||||
{ _DecodeTime(timespec, change_time, change_time_extra, extra); }
|
||||
@ -494,7 +494,7 @@ struct ext2_inode {
|
||||
time |= (uint64)timespec->tv_sec >> 32;
|
||||
return B_HOST_TO_LENDIAN_INT32(time);
|
||||
}
|
||||
|
||||
|
||||
void SetModificationTime(const struct timespec *timespec, bool extra)
|
||||
{
|
||||
modification_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec);
|
||||
@ -517,7 +517,7 @@ struct ext2_inode {
|
||||
{
|
||||
if (extra) {
|
||||
creation_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec);
|
||||
creation_time_extra =
|
||||
creation_time_extra =
|
||||
B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_nsec);
|
||||
}
|
||||
}
|
||||
@ -527,7 +527,7 @@ struct ext2_inode {
|
||||
}
|
||||
|
||||
ino_t NextOrphan() const { return (ino_t)DeletionTime(); }
|
||||
|
||||
|
||||
off_t Size() const
|
||||
{
|
||||
if (S_ISREG(Mode())) {
|
||||
@ -654,6 +654,10 @@ struct ext2_inode {
|
||||
#define EXT2_INODE_DIR_SYNCH 0x00010000
|
||||
#define EXT2_INODE_HUGE_FILE 0x00040000
|
||||
#define EXT2_INODE_EXTENTS 0x00080000
|
||||
#define EXT2_INODE_LARGE_EA 0x00200000
|
||||
#define EXT2_INODE_EOF_BLOCKS 0x00400000
|
||||
#define EXT2_INODE_INLINE_DATA 0x10000000
|
||||
#define EXT2_INODE_RESERVED 0x80000000
|
||||
|
||||
#define EXT2_INODE_INHERITED (EXT2_INODE_SECURE_DELETION | EXT2_INODE_UNDELETE \
|
||||
| EXT2_INODE_COMPRESSED | EXT2_INODE_SYNCHRONOUS | EXT2_INODE_IMMUTABLE \
|
||||
|
@ -274,7 +274,9 @@ fs_identify_partition(int fd, partition_data *partition, void **_cookie)
|
||||
|
||||
*_cookie = cookie;
|
||||
|
||||
return 0.8f;
|
||||
// Make sure we return a higher number than the intel partition check
|
||||
// as this one is more accurate.
|
||||
return 0.82f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ dpc_thread(void *arg)
|
||||
}
|
||||
|
||||
// Let's finish the pending DPCs, if any.
|
||||
// Otherwise, resource could leaks...
|
||||
// Otherwise, resource could leak...
|
||||
while (queue->count--) {
|
||||
dpc = queue->slots[queue->head];
|
||||
queue->head = (queue->head + 1) % queue->size;
|
||||
@ -135,7 +135,7 @@ delete_dpc_queue(void *handle)
|
||||
if (!queue)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// Close the queue: queue_dpc() should knows we're closing:
|
||||
// Close the queue: queue_dpc() should know we're closing:
|
||||
former = disable_interrupts();
|
||||
acquire_spinlock(&queue->lock);
|
||||
|
||||
@ -186,8 +186,8 @@ queue_dpc(void *handle, dpc_func function, void *arg)
|
||||
restore_interrupts(former);
|
||||
|
||||
if (status == B_OK)
|
||||
// Wake up the corresponding dpc thead
|
||||
// Notice that interrupt handlers should returns B_INVOKE_SCHEDULER to
|
||||
// Wake up the corresponding dpc thread
|
||||
// Notice that interrupt handlers should return B_INVOKE_SCHEDULER to
|
||||
// shorten DPC latency as much as possible...
|
||||
status = release_sem_etc(queue->wakeup_sem, 1, B_DO_NOT_RESCHEDULE);
|
||||
|
||||
|
@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
|
||||
|
||||
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
MergeObject DebugAnalyzer_gui.o
|
||||
:
|
||||
AbstractGeneralPage.cpp
|
||||
|
@ -4,9 +4,6 @@ UsePrivateHeaders shared ;
|
||||
|
||||
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
MergeObject DebugAnalyzer_gui_chart.o
|
||||
:
|
||||
BigtimeChartAxisLegendSource.cpp
|
||||
|
@ -7,9 +7,6 @@ UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src apps debugger util ] ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
MergeObject DebugAnalyzer_gui_main_window.o
|
||||
:
|
||||
GeneralPage.cpp
|
||||
|
@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
|
||||
|
||||
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
MergeObject DebugAnalyzer_gui_table.o
|
||||
:
|
||||
AbstractTable.cpp
|
||||
|
@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
|
||||
|
||||
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
MergeObject DebugAnalyzer_gui_thread_window.o
|
||||
:
|
||||
ActivityPage.cpp
|
||||
|
@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
|
||||
|
||||
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
MergeObject DebugAnalyzer_model.o
|
||||
:
|
||||
Model.cpp
|
||||
|
@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
|
||||
|
||||
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
MergeObject DebugAnalyzer_model_loader.o
|
||||
:
|
||||
AbstractModelLoader.cpp
|
||||
|
@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
|
||||
|
||||
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
MergeObject DebugAnalyzer_util.o
|
||||
:
|
||||
DataSource.cpp
|
||||
|
@ -1,8 +1,5 @@
|
||||
SubDir HAIKU_TOP src apps debugger ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
||||
|
||||
# for syscall_numbers.h
|
||||
@ -184,6 +181,7 @@ Application Debugger :
|
||||
BreakpointSetting.cpp
|
||||
GuiTeamUiSettings.cpp
|
||||
SettingsManager.cpp
|
||||
TeamFileManagerSettings.cpp
|
||||
TeamSettings.cpp
|
||||
TeamUiSettings.cpp
|
||||
TeamUiSettingsFactory.cpp
|
||||
|
@ -1,8 +1,5 @@
|
||||
SubDir HAIKU_TOP src apps debugger arch x86 disasm ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
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
|
||||
// stack.
|
||||
uint32 rsp = cpuState->IntRegisterValue(X86_64_REGISTER_RSP);
|
||||
uint32 address;
|
||||
uint64 rsp = cpuState->IntRegisterValue(X86_64_REGISTER_RSP);
|
||||
uint64 address;
|
||||
if (fTeamMemory->ReadMemory(rsp, &address, 8) == 8) {
|
||||
returnAddress = address;
|
||||
previousFramePointer = framePointer;
|
||||
|
@ -1,8 +1,5 @@
|
||||
SubDir HAIKU_TOP src apps debugger arch x86_64 disasm ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
UseHeaders [ LibraryHeaders udis86 ] ;
|
||||
|
@ -18,12 +18,15 @@
|
||||
#include "AreaInfo.h"
|
||||
#include "CpuState.h"
|
||||
#include "DebuggerInterface.h"
|
||||
#include "DisassembledCode.h"
|
||||
#include "FunctionInstance.h"
|
||||
#include "Image.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "Register.h"
|
||||
#include "SemaphoreInfo.h"
|
||||
#include "StackFrame.h"
|
||||
#include "StackTrace.h"
|
||||
#include "Statement.h"
|
||||
#include "StringUtils.h"
|
||||
#include "SystemInfo.h"
|
||||
#include "Team.h"
|
||||
@ -51,7 +54,8 @@ DebugReportGenerator::DebugReportGenerator(::Team* team,
|
||||
fWaitingNode(NULL),
|
||||
fCurrentBlock(NULL),
|
||||
fBlockRetrievalStatus(B_OK),
|
||||
fTraceWaitingThread(NULL)
|
||||
fTraceWaitingThread(NULL),
|
||||
fSourceWaitingFunction(NULL)
|
||||
{
|
||||
fTeam->AddListener(this);
|
||||
fArchitecture->AcquireReference();
|
||||
@ -204,6 +208,20 @@ DebugReportGenerator::ValueNodeValueChanged(ValueNode* node)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DebugReportGenerator::FunctionSourceCodeChanged(Function* function)
|
||||
{
|
||||
AutoLocker< ::Team> teamLocker(fTeam);
|
||||
if (function == fSourceWaitingFunction) {
|
||||
if (function->FirstInstance()->SourceCodeState()
|
||||
== FUNCTION_SOURCE_LOADED
|
||||
|| function->FirstInstance()->SourceCodeState()
|
||||
== FUNCTION_SOURCE_UNAVAILABLE) {
|
||||
release_sem(fTeamDataSem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status_t
|
||||
DebugReportGenerator::_GenerateReportHeader(BString& _output)
|
||||
{
|
||||
@ -452,9 +470,12 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output,
|
||||
&& frame->CountLocalVariables() == 0) {
|
||||
// only dump the topmost frame
|
||||
if (i == 0) {
|
||||
locker.Unlock();
|
||||
_DumpFunctionDisassembly(_output, frame->InstructionPointer());
|
||||
_DumpStackFrameMemory(_output, thread->GetCpuState(),
|
||||
frame->FrameAddress(), thread->GetTeam()->GetArchitecture()
|
||||
->StackGrowthDirection());
|
||||
locker.Lock();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -495,6 +516,66 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DebugReportGenerator::_DumpFunctionDisassembly(BString& _output,
|
||||
target_addr_t instructionPointer)
|
||||
{
|
||||
AutoLocker< ::Team> teamLocker(fTeam);
|
||||
BString data;
|
||||
FunctionInstance* instance = NULL;
|
||||
Statement* statement = NULL;
|
||||
status_t error = fTeam->GetStatementAtAddress(instructionPointer, instance,
|
||||
statement);
|
||||
if (error != B_OK) {
|
||||
data.SetToFormat("Unable to retrieve disassembly for IP %#" B_PRIx64
|
||||
": %s\n", instructionPointer, strerror(error));
|
||||
_output << data;
|
||||
return;
|
||||
}
|
||||
|
||||
DisassembledCode* code = instance->GetSourceCode();
|
||||
Function* function = instance->GetFunction();
|
||||
if (code == NULL) {
|
||||
switch (function->SourceCodeState()) {
|
||||
case FUNCTION_SOURCE_NOT_LOADED:
|
||||
function->AddListener(this);
|
||||
fSourceWaitingFunction = function;
|
||||
fListener->FunctionSourceCodeRequested(instance, true);
|
||||
// fall through
|
||||
case FUNCTION_SOURCE_LOADING:
|
||||
{
|
||||
teamLocker.Unlock();
|
||||
error = acquire_sem(fTeamDataSem);
|
||||
if (error != B_OK)
|
||||
return;
|
||||
teamLocker.Lock();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance->SourceCodeState() == FUNCTION_SOURCE_UNAVAILABLE)
|
||||
return;
|
||||
|
||||
error = fTeam->GetStatementAtAddress(instructionPointer, instance,
|
||||
statement);
|
||||
code = instance->GetSourceCode();
|
||||
}
|
||||
|
||||
SourceLocation location = statement->StartSourceLocation();
|
||||
|
||||
_output << "\t\t\tDisassembly:\n";
|
||||
for (int32 i = 0; i < location.Line(); i++) {
|
||||
_output << "\t\t\t\t" << code->LineAt(i);
|
||||
if (i == location.Line() - 1)
|
||||
_output << " <--";
|
||||
_output << "\n";
|
||||
}
|
||||
_output << "\n";
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DebugReportGenerator::_DumpStackFrameMemory(BString& _output,
|
||||
CpuState* state, target_addr_t framePointer, uint8 stackDirection)
|
||||
@ -519,11 +600,11 @@ DebugReportGenerator::_DumpStackFrameMemory(BString& _output,
|
||||
|
||||
_output << "\t\t\tFrame memory:\n";
|
||||
if (fBlockRetrievalStatus == B_OK) {
|
||||
UiUtils::DumpMemory(_output, 3, fCurrentBlock, startAddress, 1, 16,
|
||||
UiUtils::DumpMemory(_output, 4 , fCurrentBlock, startAddress, 1, 16,
|
||||
endAddress - startAddress);
|
||||
} else {
|
||||
BString data;
|
||||
data.SetToFormat("\t\t\tUnavailable (%s)\n", strerror(
|
||||
data.SetToFormat("\t\t\t\tUnavailable (%s)\n", strerror(
|
||||
fBlockRetrievalStatus));
|
||||
_output += data;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <Looper.h>
|
||||
|
||||
#include "Function.h"
|
||||
#include "Team.h"
|
||||
#include "TeamMemoryBlock.h"
|
||||
#include "ValueNodeContainer.h"
|
||||
@ -30,7 +31,8 @@ class ValueNodeManager;
|
||||
|
||||
|
||||
class DebugReportGenerator : public BLooper, private Team::Listener,
|
||||
private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener {
|
||||
private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener,
|
||||
private Function::Listener {
|
||||
public:
|
||||
DebugReportGenerator(::Team* team,
|
||||
UserInterfaceListener* listener,
|
||||
@ -58,6 +60,8 @@ private:
|
||||
// ValueNodeContainer::Listener
|
||||
virtual void ValueNodeValueChanged(ValueNode* node);
|
||||
|
||||
// Function::Listener
|
||||
virtual void FunctionSourceCodeChanged(Function* function);
|
||||
|
||||
private:
|
||||
status_t _GenerateReport(const entry_ref& outputPath);
|
||||
@ -68,6 +72,8 @@ private:
|
||||
status_t _DumpRunningThreads(BString& _output);
|
||||
status_t _DumpDebuggedThreadInfo(BString& _output,
|
||||
::Thread* thread);
|
||||
void _DumpFunctionDisassembly(BString& _output,
|
||||
target_addr_t instructionPointer);
|
||||
void _DumpStackFrameMemory(BString& _output,
|
||||
CpuState* state,
|
||||
target_addr_t framePointer,
|
||||
@ -97,6 +103,7 @@ private:
|
||||
TeamMemoryBlock* fCurrentBlock;
|
||||
status_t fBlockRetrievalStatus;
|
||||
::Thread* fTraceWaitingThread;
|
||||
Function* fSourceWaitingFunction;
|
||||
};
|
||||
|
||||
#endif // DEBUG_REPORT_GENERATOR_H
|
||||
|
@ -1991,6 +1991,8 @@ TeamDebugger::_LoadSettings()
|
||||
breakpointSetting->IsEnabled());
|
||||
}
|
||||
|
||||
fFileManager->LoadLocationMappings(fTeamSettings.FileManagerSettings());
|
||||
|
||||
const TeamUiSettings* uiSettings = fTeamSettings.UiSettingFor(
|
||||
fUserInterface->ID());
|
||||
if (uiSettings != NULL)
|
||||
@ -2022,6 +2024,8 @@ TeamDebugger::_SaveSettings()
|
||||
settings.AddUiSettings(clonedSettings);
|
||||
}
|
||||
}
|
||||
|
||||
fFileManager->SaveLocationMappings(settings.FileManagerSettings());
|
||||
locker.Unlock();
|
||||
|
||||
// save the settings
|
||||
|
@ -1,8 +1,5 @@
|
||||
SubDir HAIKU_TOP src apps debugger demangler ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
SEARCH_SOURCE
|
||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel debugger demangle ] ;
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
SubDir HAIKU_TOP src apps debugger dwarf ;
|
||||
|
||||
CCFLAGS += -Werror ;
|
||||
C++FLAGS += -Werror ;
|
||||
|
||||
UsePrivateHeaders kernel shared ;
|
||||
UsePrivateSystemHeaders ;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2011-2012, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2011-2013, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "LocatableFile.h"
|
||||
#include "SourceFile.h"
|
||||
#include "StringUtils.h"
|
||||
#include "TeamFileManagerSettings.h"
|
||||
|
||||
|
||||
// #pragma mark - EntryPath
|
||||
@ -611,7 +612,8 @@ FileManager::GetTargetFile(const BString& path)
|
||||
|
||||
|
||||
void
|
||||
FileManager::TargetEntryLocated(const BString& path, const BString& locatedPath)
|
||||
FileManager::TargetEntryLocated(const BString& path,
|
||||
const BString& locatedPath)
|
||||
{
|
||||
AutoLocker<FileManager> locker(this);
|
||||
fTargetDomain->EntryLocated(path, locatedPath);
|
||||
@ -623,7 +625,14 @@ FileManager::GetSourceFile(const BString& directory,
|
||||
const BString& relativePath)
|
||||
{
|
||||
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)
|
||||
{
|
||||
AutoLocker<FileManager> locker(this);
|
||||
return fSourceDomain->GetFile(path);
|
||||
LocatableFile* file = fSourceDomain->GetFile(path);
|
||||
_LocateFileIfMapped(path, file);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileManager::SourceEntryLocated(const BString& path, const BString& locatedPath)
|
||||
status_t
|
||||
FileManager::SourceEntryLocated(const BString& path,
|
||||
const BString& locatedPath)
|
||||
{
|
||||
AutoLocker<FileManager> locker(this);
|
||||
fSourceDomain->EntryLocated(path, locatedPath);
|
||||
|
||||
try {
|
||||
fSourceLocationMappings[path] = locatedPath;
|
||||
} catch (...) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -687,6 +708,45 @@ FileManager::LoadSourceFile(LocatableFile* file, SourceFile*& _sourceFile)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FileManager::LoadLocationMappings(TeamFileManagerSettings* settings)
|
||||
{
|
||||
AutoLocker<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::_LookupSourceFile(const BString& path)
|
||||
{
|
||||
@ -713,3 +773,17 @@ FileManager::_SourceFileUnused(SourceFileEntry* entry)
|
||||
if (otherEntry == entry)
|
||||
fSourceFiles->Remove(entry);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileManager::_LocateFileIfMapped(const BString& sourcePath,
|
||||
LocatableFile* file)
|
||||
{
|
||||
// called with lock held
|
||||
LocatedFileMap::const_iterator it = fSourceLocationMappings.find(
|
||||
sourcePath);
|
||||
if (it != fSourceLocationMappings.end()
|
||||
&& file->State() != LOCATABLE_ENTRY_LOCATED_EXPLICITLY) {
|
||||
fSourceDomain->EntryLocated(it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FILE_MANAGER_H
|
||||
#define FILE_MANAGER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <Locker.h>
|
||||
#include <Message.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <util/DoublyLinkedList.h>
|
||||
@ -15,6 +19,7 @@
|
||||
class LocatableEntry;
|
||||
class LocatableFile;
|
||||
class SourceFile;
|
||||
class TeamFileManagerSettings;
|
||||
|
||||
|
||||
class FileManager {
|
||||
@ -40,13 +45,18 @@ public:
|
||||
// returns a reference
|
||||
LocatableFile* GetSourceFile(const BString& path);
|
||||
// returns a reference
|
||||
void SourceEntryLocated(const BString& path,
|
||||
status_t SourceEntryLocated(const BString& path,
|
||||
const BString& locatedPath);
|
||||
|
||||
status_t LoadSourceFile(LocatableFile* file,
|
||||
SourceFile*& _sourceFile);
|
||||
// returns a reference
|
||||
|
||||
status_t LoadLocationMappings(TeamFileManagerSettings*
|
||||
settings);
|
||||
status_t SaveLocationMappings(TeamFileManagerSettings*
|
||||
settings);
|
||||
|
||||
private:
|
||||
struct EntryPath;
|
||||
struct EntryHashDefinition;
|
||||
@ -57,6 +67,7 @@ private:
|
||||
typedef BOpenHashTable<EntryHashDefinition> LocatableEntryTable;
|
||||
typedef DoublyLinkedList<LocatableEntry> DeadEntryList;
|
||||
typedef BOpenHashTable<SourceFileHashDefinition> SourceFileTable;
|
||||
typedef std::map<BString, BString> LocatedFileMap;
|
||||
|
||||
friend struct SourceFileEntry;
|
||||
// for gcc 2
|
||||
@ -64,12 +75,16 @@ private:
|
||||
private:
|
||||
SourceFileEntry* _LookupSourceFile(const BString& path);
|
||||
void _SourceFileUnused(SourceFileEntry* entry);
|
||||
void _LocateFileIfMapped(const BString& sourcePath,
|
||||
LocatableFile* file);
|
||||
|
||||
private:
|
||||
BLocker fLock;
|
||||
Domain* fTargetDomain;
|
||||
Domain* fSourceDomain;
|
||||
SourceFileTable* fSourceFiles;
|
||||
|
||||
LocatedFileMap fSourceLocationMappings;
|
||||
};
|
||||
|
||||
|
||||
|
128
src/apps/debugger/settings/TeamFileManagerSettings.cpp
Normal file
128
src/apps/debugger/settings/TeamFileManagerSettings.cpp
Normal file
@ -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;
|
||||
}
|
41
src/apps/debugger/settings/TeamFileManagerSettings.h
Normal file
41
src/apps/debugger/settings/TeamFileManagerSettings.h
Normal file
@ -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 "BreakpointSetting.h"
|
||||
#include "Team.h"
|
||||
#include "TeamFileManagerSettings.h"
|
||||
#include "TeamUiSettings.h"
|
||||
#include "TeamUiSettingsFactory.h"
|
||||
#include "UserBreakpoint.h"
|
||||
@ -23,6 +24,7 @@
|
||||
|
||||
TeamSettings::TeamSettings()
|
||||
{
|
||||
fFileManagerSettings = new TeamFileManagerSettings();
|
||||
}
|
||||
|
||||
|
||||
@ -115,6 +117,12 @@ TeamSettings::SetTo(const BMessage& archive)
|
||||
}
|
||||
}
|
||||
|
||||
if (archive.FindMessage("filemanagersettings", &childArchive) == B_OK) {
|
||||
error = fFileManagerSettings->SetTo(childArchive);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -149,6 +157,14 @@ TeamSettings::WriteTo(BMessage& archive) const
|
||||
return error;
|
||||
}
|
||||
|
||||
error = fFileManagerSettings->WriteTo(childArchive);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
error = archive.AddMessage("filemanagersettings", &childArchive);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -234,10 +250,32 @@ TeamSettings::operator=(const TeamSettings& other)
|
||||
}
|
||||
}
|
||||
|
||||
*fFileManagerSettings = *other.fFileManagerSettings;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TeamFileManagerSettings*
|
||||
TeamSettings::FileManagerSettings() const
|
||||
{
|
||||
return fFileManagerSettings;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
TeamSettings::SetFileManagerSettings(TeamFileManagerSettings* settings)
|
||||
{
|
||||
try {
|
||||
*fFileManagerSettings = *settings;
|
||||
} catch (...) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamSettings::_Unset()
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef TEAM_SETTINGS_H
|
||||
@ -15,6 +16,7 @@ class BMessage;
|
||||
class Team;
|
||||
class BreakpointSetting;
|
||||
class TeamUiSettings;
|
||||
class TeamFileManagerSettings;
|
||||
|
||||
|
||||
class TeamSettings {
|
||||
@ -41,6 +43,11 @@ public:
|
||||
TeamSettings& operator=(const TeamSettings& other);
|
||||
// throws std::bad_alloc
|
||||
|
||||
TeamFileManagerSettings*
|
||||
FileManagerSettings() const;
|
||||
status_t SetFileManagerSettings(
|
||||
TeamFileManagerSettings* settings);
|
||||
|
||||
private:
|
||||
typedef BObjectList<BreakpointSetting> BreakpointList;
|
||||
typedef BObjectList<TeamUiSettings> UiSettingsList;
|
||||
@ -51,6 +58,8 @@ private:
|
||||
private:
|
||||
BreakpointList fBreakpoints;
|
||||
UiSettingsList fUiSettings;
|
||||
TeamFileManagerSettings*
|
||||
fFileManagerSettings;
|
||||
BString fTeamName;
|
||||
};
|
||||
|
||||
|
@ -11,20 +11,30 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <Clipboard.h>
|
||||
#include <Looper.h>
|
||||
#include <MenuItem.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <Messenger.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <Region.h>
|
||||
#include <ScrollView.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "Architecture.h"
|
||||
#include "AutoDeleter.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "Team.h"
|
||||
#include "TeamMemoryBlock.h"
|
||||
|
||||
|
||||
enum {
|
||||
MSG_TARGET_ADDRESS_CHANGED = 'mtac'
|
||||
MSG_TARGET_ADDRESS_CHANGED = 'mtac',
|
||||
MSG_VIEW_AUTOSCROLL = 'mvas'
|
||||
};
|
||||
|
||||
static const bigtime_t kScrollTimer = 10000LL;
|
||||
|
||||
|
||||
MemoryView::MemoryView(::Team* team, Listener* listener)
|
||||
:
|
||||
@ -39,6 +49,10 @@ MemoryView::MemoryView(::Team* team, Listener* listener)
|
||||
fHexBlocksPerLine(0),
|
||||
fHexMode(HexMode8BitInt),
|
||||
fTextMode(TextModeASCII),
|
||||
fSelectionBase(0),
|
||||
fSelectionStart(0),
|
||||
fSelectionEnd(0),
|
||||
fScrollRunner(NULL),
|
||||
fListener(listener)
|
||||
{
|
||||
Architecture* architecture = team->GetArchitecture();
|
||||
@ -76,11 +90,14 @@ void
|
||||
MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address)
|
||||
{
|
||||
fTargetAddress = address;
|
||||
if (fTargetBlock != NULL)
|
||||
if (block != fTargetBlock && fTargetBlock != NULL)
|
||||
fTargetBlock->ReleaseReference();
|
||||
|
||||
fTargetBlock = block;
|
||||
fTargetBlock->AcquireReference();
|
||||
if (block != fTargetBlock) {
|
||||
fTargetBlock = block;
|
||||
fTargetBlock->AcquireReference();
|
||||
}
|
||||
|
||||
MakeFocus(true);
|
||||
BMessenger(this).SendMessage(MSG_TARGET_ADDRESS_CHANGED);
|
||||
}
|
||||
@ -119,7 +136,7 @@ MemoryView::Draw(BRect rect)
|
||||
if (fTargetBlock == NULL)
|
||||
return;
|
||||
|
||||
uint32 hexBlockSize = (1 << fHexMode) + 1;
|
||||
uint32 hexBlockSize = _GetHexDigitsPerBlock() + 1;
|
||||
uint32 blockByteSize = hexBlockSize / 2;
|
||||
if (fHexMode != HexModeNone && fTextMode != TextModeNone) {
|
||||
divider += (fHexBlocksPerLine * hexBlockSize + 1) * fCharWidth;
|
||||
@ -156,7 +173,6 @@ MemoryView::Draw(BRect rect)
|
||||
DrawString(buffer, drawPoint);
|
||||
drawPoint.x += fCharWidth * (fTargetAddressSize + 2);
|
||||
PopState();
|
||||
|
||||
if (fHexMode != HexModeNone) {
|
||||
if (currentAddress + (currentBlocksPerLine * blockByteSize)
|
||||
> maxAddress) {
|
||||
@ -168,20 +184,15 @@ MemoryView::Draw(BRect rect)
|
||||
for (int32 j = 0; j < currentBlocksPerLine; j++) {
|
||||
const char* blockAddress = currentAddress + (j
|
||||
* blockByteSize);
|
||||
_GetNextHexBlock(buffer,
|
||||
std::min((size_t)hexBlockSize, sizeof(buffer)),
|
||||
blockAddress);
|
||||
DrawString(buffer, drawPoint);
|
||||
_GetNextHexBlock(buffer, sizeof(buffer), blockAddress);
|
||||
if (targetAddress >= blockAddress && targetAddress <
|
||||
blockAddress + blockByteSize) {
|
||||
blockAddress + blockByteSize) {
|
||||
PushState();
|
||||
SetHighColor(B_TRANSPARENT_COLOR);
|
||||
SetDrawingMode(B_OP_INVERT);
|
||||
FillRect(BRect(drawPoint.x, drawPoint.y - fh.ascent,
|
||||
drawPoint.x + (hexBlockSize - 1) * fCharWidth,
|
||||
drawPoint.y + fh.descent));
|
||||
SetHighColor(make_color(216,0,0));
|
||||
DrawString(buffer, drawPoint);
|
||||
PopState();
|
||||
}
|
||||
} else
|
||||
DrawString(buffer, drawPoint);
|
||||
|
||||
drawPoint.x += fCharWidth * hexBlockSize;
|
||||
}
|
||||
@ -190,6 +201,7 @@ MemoryView::Draw(BRect rect)
|
||||
drawPoint.x += fCharWidth * hexBlockSize
|
||||
* (fHexBlocksPerLine - currentBlocksPerLine);
|
||||
}
|
||||
|
||||
if (fTextMode != TextModeNone) {
|
||||
drawPoint.x += fCharWidth;
|
||||
for (int32 j = 0; j < currentCharsPerLine; j++) {
|
||||
@ -226,6 +238,15 @@ MemoryView::Draw(BRect rect)
|
||||
lineAddress += fTextCharsPerLine;
|
||||
}
|
||||
}
|
||||
|
||||
if (fSelectionStart != fSelectionEnd) {
|
||||
PushState();
|
||||
BRegion selectionRegion;
|
||||
_GetSelectionRegion(selectionRegion);
|
||||
SetDrawingMode(B_OP_INVERT);
|
||||
FillRegion(&selectionRegion, B_SOLID_HIGH);
|
||||
PopState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -332,6 +353,11 @@ void
|
||||
MemoryView::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch(message->what) {
|
||||
case B_COPY:
|
||||
{
|
||||
_CopySelectionToClipboard();
|
||||
break;
|
||||
}
|
||||
case MSG_TARGET_ADDRESS_CHANGED:
|
||||
{
|
||||
_RecalcScrollBars();
|
||||
@ -370,6 +396,11 @@ MemoryView::MessageReceived(BMessage* message)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSG_VIEW_AUTOSCROLL:
|
||||
{
|
||||
_HandleAutoScroll();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
BView::MessageReceived(message);
|
||||
@ -385,7 +416,78 @@ MemoryView::MouseDown(BPoint point)
|
||||
if (!IsFocus())
|
||||
MakeFocus(true);
|
||||
|
||||
BView::MouseDown(point);
|
||||
if (fTargetBlock == NULL)
|
||||
return;
|
||||
|
||||
int32 buttons;
|
||||
if (Looper()->CurrentMessage()->FindInt32("buttons", &buttons) != B_OK)
|
||||
buttons = B_PRIMARY_MOUSE_BUTTON;
|
||||
|
||||
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
||||
_HandleContextMenu(point);
|
||||
return;
|
||||
}
|
||||
|
||||
int32 offset = _GetOffsetAt(point);
|
||||
if (offset < fSelectionStart || offset > fSelectionEnd) {
|
||||
BRegion oldSelectionRegion;
|
||||
_GetSelectionRegion(oldSelectionRegion);
|
||||
fSelectionBase = offset;
|
||||
fSelectionStart = fSelectionBase;
|
||||
fSelectionEnd = fSelectionBase;
|
||||
Invalidate(oldSelectionRegion.Frame());
|
||||
}
|
||||
|
||||
SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
|
||||
fTrackingMouse = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::MouseMoved(BPoint point, uint32 transit, const BMessage* message)
|
||||
{
|
||||
if (!fTrackingMouse)
|
||||
return;
|
||||
|
||||
BRegion oldSelectionRegion;
|
||||
_GetSelectionRegion(oldSelectionRegion);
|
||||
int32 offset = _GetOffsetAt(point);
|
||||
if (offset < fSelectionBase) {
|
||||
fSelectionStart = offset;
|
||||
fSelectionEnd = fSelectionBase;
|
||||
} else {
|
||||
fSelectionStart = fSelectionBase;
|
||||
fSelectionEnd = offset;
|
||||
}
|
||||
|
||||
BRegion region;
|
||||
_GetSelectionRegion(region);
|
||||
region.Include(&oldSelectionRegion);
|
||||
Invalidate(region.Frame());
|
||||
|
||||
switch (transit) {
|
||||
case B_EXITED_VIEW:
|
||||
fScrollRunner = new BMessageRunner(BMessenger(this),
|
||||
new BMessage(MSG_VIEW_AUTOSCROLL), kScrollTimer);
|
||||
break;
|
||||
|
||||
case B_ENTERED_VIEW:
|
||||
delete fScrollRunner;
|
||||
fScrollRunner = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::MouseUp(BPoint point)
|
||||
{
|
||||
fTrackingMouse = false;
|
||||
delete fScrollRunner;
|
||||
fScrollRunner = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -395,10 +497,12 @@ MemoryView::ScrollToSelection()
|
||||
if (fTargetBlock != NULL) {
|
||||
target_addr_t offset = fTargetAddress - fTargetBlock->BaseAddress();
|
||||
int32 lineNumber = 0;
|
||||
if (fHexBlocksPerLine > 0)
|
||||
lineNumber = offset / (fHexBlocksPerLine * (1 << (fHexMode - 1)));
|
||||
else if (fTextCharsPerLine > 0)
|
||||
if (fHexBlocksPerLine > 0) {
|
||||
lineNumber = offset / (fHexBlocksPerLine
|
||||
* (_GetHexDigitsPerBlock() / 2));
|
||||
} else if (fTextCharsPerLine > 0)
|
||||
lineNumber = offset / fTextCharsPerLine;
|
||||
|
||||
float y = lineNumber * fLineHeight;
|
||||
if (y < Bounds().top)
|
||||
ScrollTo(0.0, y);
|
||||
@ -429,40 +533,23 @@ MemoryView::_RecalcScrollBars()
|
||||
float max = 0.0;
|
||||
BScrollBar *scrollBar = ScrollBar(B_VERTICAL);
|
||||
if (fTargetBlock != NULL) {
|
||||
BRect bounds = Bounds();
|
||||
// the left portion of the view is off limits since it
|
||||
// houses the address offset of the current line
|
||||
float baseWidth = bounds.Width() - ((fTargetAddressSize + 2)
|
||||
* fCharWidth);
|
||||
float hexWidth = 0.0;
|
||||
float textWidth = 0.0;
|
||||
int32 hexDigits = 1 << fHexMode;
|
||||
int32 hexDigits = _GetHexDigitsPerBlock();
|
||||
int32 sizeFactor = 1 + hexDigits;
|
||||
if (fHexMode != HexModeNone) {
|
||||
if (fTextMode != TextModeNone) {
|
||||
float hexProportion = sizeFactor / (float)(sizeFactor
|
||||
+ hexDigits / 2);
|
||||
hexWidth = baseWidth * hexProportion;
|
||||
// when sharing the display between hex and text,
|
||||
// we allocate a 2 character space to separate the views
|
||||
hexWidth -= 2 * fCharWidth;
|
||||
textWidth = baseWidth - hexWidth;
|
||||
} else
|
||||
hexWidth = baseWidth;
|
||||
} else if (fTextMode != TextModeNone)
|
||||
textWidth = baseWidth;
|
||||
_RecalcBounds();
|
||||
|
||||
float hexWidth = fHexRight - fHexLeft;
|
||||
int32 nybblesPerLine = int32(hexWidth / fCharWidth);
|
||||
fHexBlocksPerLine = 0;
|
||||
fTextCharsPerLine = 0;
|
||||
if (fHexMode != HexModeNone) {
|
||||
fHexBlocksPerLine = nybblesPerLine / sizeFactor;
|
||||
fHexBlocksPerLine &= ~1;
|
||||
fHexRight = fHexLeft + (fHexBlocksPerLine * sizeFactor
|
||||
* fCharWidth);
|
||||
if (fTextMode != TextModeNone)
|
||||
fTextCharsPerLine = fHexBlocksPerLine * hexDigits / 2;
|
||||
} else if (fTextMode != TextModeNone)
|
||||
fTextCharsPerLine = int32(textWidth / fCharWidth);
|
||||
|
||||
fTextCharsPerLine = int32((fTextRight - fTextLeft) / fCharWidth);
|
||||
int32 lineCount = 0;
|
||||
float totalHeight = 0.0;
|
||||
if (fHexBlocksPerLine > 0) {
|
||||
@ -473,6 +560,7 @@ MemoryView::_RecalcScrollBars()
|
||||
|
||||
totalHeight = lineCount * fLineHeight;
|
||||
if (totalHeight > 0.0) {
|
||||
BRect bounds = Bounds();
|
||||
max = totalHeight - bounds.Height();
|
||||
scrollBar->SetProportion(bounds.Height() / totalHeight);
|
||||
scrollBar->SetSteps(fLineHeight, bounds.Height());
|
||||
@ -488,7 +576,8 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize,
|
||||
switch(fHexMode) {
|
||||
case HexMode8BitInt:
|
||||
{
|
||||
snprintf(buffer, bufferSize, "%02" B_PRIx8, *address);
|
||||
snprintf(buffer, bufferSize, "%02" B_PRIx8,
|
||||
*((const uint8*)address));
|
||||
break;
|
||||
}
|
||||
case HexMode16BitInt:
|
||||
@ -558,6 +647,290 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize,
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
MemoryView::_GetOffsetAt(BPoint point) const
|
||||
{
|
||||
if (fTargetBlock == NULL)
|
||||
return -1;
|
||||
|
||||
// TODO: support selection in the text region as well
|
||||
if (fHexMode == HexModeNone)
|
||||
return -1;
|
||||
|
||||
int32 lineNumber = int32(point.y / fLineHeight);
|
||||
int32 charsPerBlock = _GetHexDigitsPerBlock() / 2;
|
||||
int32 totalHexBlocks = fTargetBlock->Size() / charsPerBlock;
|
||||
int32 lineCount = totalHexBlocks / fHexBlocksPerLine;
|
||||
|
||||
if (lineNumber >= lineCount)
|
||||
return -1;
|
||||
|
||||
point.x -= fHexLeft;
|
||||
if (point.x < 0)
|
||||
point.x = 0;
|
||||
else if (point.x > fHexRight)
|
||||
point.x = fHexRight;
|
||||
|
||||
float blockWidth = (charsPerBlock * 2 + 1) * fCharWidth;
|
||||
int32 containingBlock = int32(floor(point.x / blockWidth));
|
||||
|
||||
return fHexBlocksPerLine * charsPerBlock * lineNumber
|
||||
+ containingBlock * charsPerBlock;
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
MemoryView::_GetPointForOffset(int32 offset) const
|
||||
{
|
||||
BPoint point;
|
||||
int32 bytesPerLine = fHexBlocksPerLine * _GetHexDigitsPerBlock() / 2;
|
||||
int32 line = offset / bytesPerLine;
|
||||
int32 lineOffset = offset % bytesPerLine;
|
||||
|
||||
point.x = fHexLeft + (lineOffset * 2 * fCharWidth)
|
||||
+ (lineOffset * 2 * fCharWidth / _GetHexDigitsPerBlock());
|
||||
point.y = line * fLineHeight;
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_RecalcBounds()
|
||||
{
|
||||
fHexLeft = 0;
|
||||
fHexRight = 0;
|
||||
fTextLeft = 0;
|
||||
fTextRight = 0;
|
||||
|
||||
// the left bound is determined by the space taken up by the actual
|
||||
// displayed addresses.
|
||||
float left = _GetAddressDisplayWidth();
|
||||
float width = Bounds().Width() - left;
|
||||
|
||||
if (fHexMode != HexModeNone) {
|
||||
int32 hexDigits = _GetHexDigitsPerBlock();
|
||||
int32 sizeFactor = 1 + hexDigits;
|
||||
if (fTextMode != TextModeNone) {
|
||||
float hexProportion = sizeFactor / (float)(sizeFactor
|
||||
+ hexDigits / 2);
|
||||
float hexWidth = width * hexProportion;
|
||||
fTextLeft = left + hexWidth;
|
||||
fHexLeft = left;
|
||||
// when sharing the display between hex and text,
|
||||
// we allocate a 2 character space to separate the views
|
||||
hexWidth -= 2 * fCharWidth;
|
||||
fHexRight = left + hexWidth;
|
||||
} else {
|
||||
fHexLeft = left;
|
||||
fHexRight = left + width;
|
||||
}
|
||||
} else if (fTextMode != TextModeNone) {
|
||||
fTextLeft = left;
|
||||
fTextRight = left + width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
MemoryView::_GetAddressDisplayWidth() const
|
||||
{
|
||||
return (fTargetAddressSize + 2) * fCharWidth;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_GetSelectionRegion(BRegion& region)
|
||||
{
|
||||
region.MakeEmpty();
|
||||
BPoint startPoint = _GetPointForOffset(fSelectionStart);
|
||||
BPoint endPoint = _GetPointForOffset(fSelectionEnd);
|
||||
|
||||
BRect rect;
|
||||
if (startPoint.y == endPoint.y) {
|
||||
// single line case
|
||||
rect.left = startPoint.x;
|
||||
rect.top = startPoint.y;
|
||||
rect.right = endPoint.x;
|
||||
rect.bottom = endPoint.y + fLineHeight;
|
||||
region.Include(rect);
|
||||
} else {
|
||||
float currentLine = startPoint.y;
|
||||
|
||||
// first line
|
||||
rect.left = startPoint.x;
|
||||
rect.top = startPoint.y;
|
||||
rect.right = fHexRight;
|
||||
rect.bottom = startPoint.y + fLineHeight;
|
||||
region.Include(rect);
|
||||
currentLine += fLineHeight;
|
||||
|
||||
// middle region
|
||||
if (currentLine < endPoint.y) {
|
||||
rect.left = fHexLeft;
|
||||
rect.top = currentLine;
|
||||
rect.right = fHexRight;
|
||||
rect.bottom = endPoint.y;
|
||||
region.Include(rect);
|
||||
}
|
||||
|
||||
rect.left = fHexLeft;
|
||||
rect.top = endPoint.y;
|
||||
rect.right = endPoint.x;
|
||||
rect.bottom = endPoint.y + fLineHeight;
|
||||
region.Include(rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_GetSelectedText(BString& text)
|
||||
{
|
||||
if (fSelectionStart == fSelectionEnd)
|
||||
return;
|
||||
|
||||
text.Truncate(0);
|
||||
|
||||
char* data = (char *)fTargetBlock->Data() + fSelectionStart;
|
||||
int16 blockSize = _GetHexDigitsPerBlock() / 2;
|
||||
int32 count = (fSelectionEnd - fSelectionStart)
|
||||
/ blockSize;
|
||||
|
||||
char buffer[32];
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
_GetNextHexBlock(buffer, sizeof(buffer), data);
|
||||
data += blockSize;
|
||||
text << buffer;
|
||||
if (i < count - 1)
|
||||
text << " ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_CopySelectionToClipboard()
|
||||
{
|
||||
BString text;
|
||||
_GetSelectedText(text);
|
||||
|
||||
if (text.Length() > 0) {
|
||||
be_clipboard->Lock();
|
||||
be_clipboard->Data()->RemoveData("text/plain");
|
||||
be_clipboard->Data()->AddData ("text/plain",
|
||||
B_MIME_TYPE, text.String(), text.Length());
|
||||
be_clipboard->Commit();
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_HandleAutoScroll()
|
||||
{
|
||||
BPoint point;
|
||||
uint32 buttons;
|
||||
GetMouse(&point, &buttons);
|
||||
float difference = 0.0;
|
||||
int factor = 0;
|
||||
BRect visibleRect = Bounds();
|
||||
if (point.y < visibleRect.top)
|
||||
difference = point.y - visibleRect.top;
|
||||
else if (point.y > visibleRect.bottom)
|
||||
difference = point.y - visibleRect.bottom;
|
||||
if (difference != 0.0) {
|
||||
factor = (int)(ceilf(difference / fLineHeight));
|
||||
_ScrollByLines(factor);
|
||||
}
|
||||
|
||||
MouseMoved(point, B_OUTSIDE_VIEW, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_ScrollByLines(int32 lineCount)
|
||||
{
|
||||
BScrollBar* vertical = ScrollBar(B_VERTICAL);
|
||||
if (vertical == NULL)
|
||||
return;
|
||||
|
||||
float value = vertical->Value();
|
||||
vertical->SetValue(value + fLineHeight * lineCount);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_HandleContextMenu(BPoint point)
|
||||
{
|
||||
int32 offset = _GetOffsetAt(point);
|
||||
if (offset < fSelectionStart || offset > fSelectionEnd)
|
||||
return;
|
||||
|
||||
BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("Options");
|
||||
if (menu == NULL)
|
||||
return;
|
||||
|
||||
ObjectDeleter<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
|
||||
|
||||
|
||||
|
@ -38,9 +38,9 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
class BMessageRunner;
|
||||
|
||||
class Team;
|
||||
|
||||
|
||||
class TeamMemoryBlock;
|
||||
|
||||
|
||||
@ -66,6 +66,9 @@ public:
|
||||
virtual void MakeFocus(bool isFocused);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void MouseDown(BPoint point);
|
||||
virtual void MouseMoved(BPoint point, uint32 transit,
|
||||
const BMessage* dragMessage);
|
||||
virtual void MouseUp(BPoint point);
|
||||
void ScrollToSelection();
|
||||
virtual void TargetedByScrollView(BScrollView* scrollView);
|
||||
|
||||
@ -75,6 +78,22 @@ private:
|
||||
void _GetNextHexBlock(char* buffer,
|
||||
int32 bufferSize, const char* address);
|
||||
|
||||
int32 _GetOffsetAt(BPoint point) const;
|
||||
BPoint _GetPointForOffset(int32 offset) const;
|
||||
void _RecalcBounds();
|
||||
float _GetAddressDisplayWidth() const;
|
||||
|
||||
inline int32 _GetHexDigitsPerBlock() const
|
||||
{ return 1 << fHexMode; };
|
||||
|
||||
void _GetSelectionRegion(BRegion& region);
|
||||
void _GetSelectedText(BString& text);
|
||||
void _CopySelectionToClipboard();
|
||||
|
||||
void _HandleAutoScroll();
|
||||
void _ScrollByLines(int32 lineCount);
|
||||
void _HandleContextMenu(BPoint point);
|
||||
|
||||
private:
|
||||
::Team* fTeam;
|
||||
TeamMemoryBlock* fTargetBlock;
|
||||
@ -87,6 +106,17 @@ private:
|
||||
int32 fCurrentEndianMode;
|
||||
int32 fHexMode;
|
||||
int32 fTextMode;
|
||||
float fHexLeft;
|
||||
float fHexRight;
|
||||
float fTextLeft;
|
||||
float fTextRight;
|
||||
int32 fSelectionBase;
|
||||
int32 fSelectionStart;
|
||||
int32 fSelectionEnd;
|
||||
BMessageRunner* fScrollRunner;
|
||||
|
||||
bool fTrackingMouse;
|
||||
|
||||
Listener* fListener;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2011, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2011-2013, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -11,12 +11,17 @@
|
||||
#include <new>
|
||||
|
||||
#include <ControlLook.h>
|
||||
#include <MenuItem.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "table/TableColumns.h"
|
||||
|
||||
#include "Architecture.h"
|
||||
#include "AutoDeleter.h"
|
||||
#include "CpuState.h"
|
||||
#include "GuiSettingsUtils.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "Register.h"
|
||||
#include "UiUtils.h"
|
||||
|
||||
@ -229,6 +234,48 @@ RegistersView::TableRowInvoked(Table* table, int32 rowIndex)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RegistersView::TableCellMouseDown(Table* table, int32 rowIndex,
|
||||
int32 columnIndex, BPoint screenWhere, uint32 buttons)
|
||||
{
|
||||
if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0)
|
||||
return;
|
||||
|
||||
BVariant value;
|
||||
if (!fRegisterTableModel->GetValueAt(rowIndex, 1, value))
|
||||
return;
|
||||
|
||||
BPopUpMenu* menu = new(std::nothrow)BPopUpMenu("Options");
|
||||
if (menu == NULL)
|
||||
return;
|
||||
|
||||
ObjectDeleter<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
|
||||
RegistersView::_Init()
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef REGISTERS_VIEW_H
|
||||
@ -35,6 +36,10 @@ private:
|
||||
// TableListener
|
||||
virtual void TableRowInvoked(Table* table, int32 rowIndex);
|
||||
|
||||
virtual void TableCellMouseDown(Table* table, int32 rowIndex,
|
||||
int32 columnIndex, BPoint screenWhere,
|
||||
uint32 buttons);
|
||||
|
||||
void _Init();
|
||||
|
||||
private:
|
||||
|
@ -2103,7 +2103,7 @@ status_t
|
||||
VariablesView::_AddContextAction(const char* action, uint32 what,
|
||||
ContextActionList* actions, BMessage*& _message)
|
||||
{
|
||||
_message = new BMessage(what);
|
||||
_message = new(std::nothrow) BMessage(what);
|
||||
if (_message == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
|
@ -38,6 +38,7 @@ Application HaikuDepot :
|
||||
MainWindow.cpp
|
||||
Model.cpp
|
||||
PackageInfo.cpp
|
||||
PackageInfoListener.cpp
|
||||
PackageInfoView.cpp
|
||||
PackageListView.cpp
|
||||
PackageManager.cpp
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Autolock.h>
|
||||
#include <Application.h>
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
@ -39,8 +40,8 @@ MainWindow::MainWindow(BRect frame)
|
||||
_BuildMenu(menuBar);
|
||||
|
||||
fFilterView = new FilterView(fModel);
|
||||
fPackageListView = new PackageListView();
|
||||
fPackageInfoView = new PackageInfoView(&fPackageManager);
|
||||
fPackageListView = new PackageListView(fModel.Lock());
|
||||
fPackageInfoView = new PackageInfoView(fModel.Lock(), &fPackageManager);
|
||||
|
||||
fSplitView = new BSplitView(B_VERTICAL, 5.0f);
|
||||
|
||||
@ -87,14 +88,22 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
switch (message->what) {
|
||||
case B_SIMPLE_DATA:
|
||||
case B_REFS_RECEIVED:
|
||||
// TODO: ?
|
||||
break;
|
||||
|
||||
case MSG_PACKAGE_SELECTED:
|
||||
{
|
||||
int32 index;
|
||||
if (message->FindInt32("index", &index) == B_OK
|
||||
&& index >= 0 && index < fVisiblePackages.CountItems()) {
|
||||
_AdoptPackage(fVisiblePackages.ItemAtFast(index));
|
||||
BString title;
|
||||
if (message->FindString("title", &title) == B_OK) {
|
||||
int count = fVisiblePackages.CountItems();
|
||||
for (int i = 0; i < count; i++) {
|
||||
const PackageInfoRef& package
|
||||
= fVisiblePackages.ItemAtFast(i);
|
||||
if (package.Get() != NULL && package->Title() == title) {
|
||||
_AdoptPackage(package);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_ClearPackage();
|
||||
}
|
||||
@ -154,15 +163,17 @@ MainWindow::_AdoptModel()
|
||||
|
||||
fPackageListView->Clear();
|
||||
for (int32 i = 0; i < fVisiblePackages.CountItems(); i++) {
|
||||
BAutolock _(fModel.Lock());
|
||||
fPackageListView->AddPackage(fVisiblePackages.ItemAtFast(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_AdoptPackage(const PackageInfo& package)
|
||||
MainWindow::_AdoptPackage(const PackageInfoRef& package)
|
||||
{
|
||||
fPackageInfoView->SetPackage(package);
|
||||
fModel.PopulatePackage(package);
|
||||
}
|
||||
|
||||
|
||||
@ -176,14 +187,17 @@ MainWindow::_ClearPackage()
|
||||
void
|
||||
MainWindow::_InitDummyModel()
|
||||
{
|
||||
// TODO: The Model could be filled from another thread by
|
||||
// sending messages which contain collected package information.
|
||||
// The Model could be cached on disk.
|
||||
// TODO: The Model needs to be filled initially by the Package Kit APIs.
|
||||
// It already caches information locally. Error handlers need to be
|
||||
// installed to display problems to the user. When a package is selected
|
||||
// for display, extra information is retrieved like screen-shots, user-
|
||||
// ratings and so on. This triggers notifications which in turn updates
|
||||
// the UI.
|
||||
|
||||
DepotInfo depot(B_TRANSLATE("Default"));
|
||||
|
||||
// WonderBrush
|
||||
PackageInfo wonderbrush(
|
||||
PackageInfoRef wonderbrush(new(std::nothrow) PackageInfo(
|
||||
BitmapRef(new SharedBitmap(601), true),
|
||||
"WonderBrush",
|
||||
"2.1.2",
|
||||
@ -196,24 +210,14 @@ MainWindow::_InitDummyModel()
|
||||
"WonderBrush is YellowBites' software for doing graphics design "
|
||||
"on Haiku. It combines many great under-the-hood features with "
|
||||
"powerful tools and an efficient and intuitive interface.",
|
||||
"2.1.2 - Initial Haiku release.");
|
||||
wonderbrush.AddUserRating(
|
||||
UserRating(UserInfo("humdinger"), 4.5f,
|
||||
"Awesome!", "en", "2.1.2", 0, 0)
|
||||
);
|
||||
wonderbrush.AddUserRating(
|
||||
UserRating(UserInfo("bonefish"), 5.0f,
|
||||
"The best!", "en", "2.1.2", 3, 1)
|
||||
);
|
||||
wonderbrush.AddScreenshot(
|
||||
BitmapRef(new SharedBitmap(603), true));
|
||||
wonderbrush.AddCategory(fModel.CategoryGraphics());
|
||||
wonderbrush.AddCategory(fModel.CategoryProductivity());
|
||||
"2.1.2 - Initial Haiku release."), true);
|
||||
wonderbrush->AddCategory(fModel.CategoryGraphics());
|
||||
wonderbrush->AddCategory(fModel.CategoryProductivity());
|
||||
|
||||
depot.AddPackage(wonderbrush);
|
||||
|
||||
// Paladin
|
||||
PackageInfo paladin(
|
||||
PackageInfoRef paladin(new(std::nothrow) PackageInfo(
|
||||
BitmapRef(new SharedBitmap(602), true),
|
||||
"Paladin",
|
||||
"1.2.0",
|
||||
@ -227,30 +231,13 @@ MainWindow::_InitDummyModel()
|
||||
"The interface is streamlined, it has some features sorely "
|
||||
"missing from BeIDE, like running a project in the Terminal, "
|
||||
"and has a bundled text editor based upon Pe.",
|
||||
"");
|
||||
paladin.AddUserRating(
|
||||
UserRating(UserInfo("stippi"), 3.5f,
|
||||
"Could be more integrated from the sounds of it.",
|
||||
"en", "1.2.0", 0, 1)
|
||||
);
|
||||
paladin.AddUserRating(
|
||||
UserRating(UserInfo("mmadia"), 5.0f,
|
||||
"It rocks! Give a try",
|
||||
"en", "1.1.0", 1, 0)
|
||||
);
|
||||
paladin.AddUserRating(
|
||||
UserRating(UserInfo("bonefish"), 2.0f,
|
||||
"It just needs to use my jam-rewrite 'ham' and it will be great.",
|
||||
"en", "1.1.0", 3, 1)
|
||||
);
|
||||
paladin.AddScreenshot(
|
||||
BitmapRef(new SharedBitmap(605), true));
|
||||
paladin.AddCategory(fModel.CategoryDevelopment());
|
||||
""), true);
|
||||
paladin->AddCategory(fModel.CategoryDevelopment());
|
||||
|
||||
depot.AddPackage(paladin);
|
||||
|
||||
// Sequitur
|
||||
PackageInfo sequitur(
|
||||
PackageInfoRef sequitur(new(std::nothrow) PackageInfo(
|
||||
BitmapRef(new SharedBitmap(604), true),
|
||||
"Sequitur",
|
||||
"2.1.0",
|
||||
@ -314,26 +301,8 @@ MainWindow::_InitDummyModel()
|
||||
"pressure events. The new tool Broken Down Line uses this "
|
||||
"filter.\n\n"
|
||||
" * ''Note to filter developers:'' The filter API has changed. You "
|
||||
"will need to recompile your filters.");
|
||||
sequitur.AddUserRating(
|
||||
UserRating(UserInfo("pete"), 4.5f,
|
||||
"I can weave a web of sound! And it connects to PatchBay. Check "
|
||||
"it out, I can wholeheartly recommend this app!! This rating "
|
||||
"comment is of course only so long, because the new TextView "
|
||||
"layout needs some testing. Oh, and did I mention it works with "
|
||||
"custom installed sound fonts? Reading through this comment I find "
|
||||
"that I did not until now. Hopefully there are enough lines now to "
|
||||
"please the programmer with the text layouting and scrolling of "
|
||||
"long ratings!", "en", "2.1.0", 4, 1)
|
||||
);
|
||||
sequitur.AddUserRating(
|
||||
UserRating(UserInfo("stippi"), 3.5f,
|
||||
"It seems very capable. Still runs fine on Haiku. The interface "
|
||||
"is composed of many small, hard to click items. But you can "
|
||||
"configure a tool for each mouse button, which is great for the "
|
||||
"work flow.", "en", "2.1.0", 2, 1)
|
||||
);
|
||||
sequitur.AddCategory(fModel.CategoryAudio());
|
||||
"will need to recompile your filters."), true);
|
||||
sequitur->AddCategory(fModel.CategoryAudio());
|
||||
|
||||
depot.AddPackage(sequitur);
|
||||
|
||||
|
@ -35,7 +35,7 @@ private:
|
||||
void _BuildMenu(BMenuBar* menuBar);
|
||||
void _AdoptModel();
|
||||
|
||||
void _AdoptPackage(const PackageInfo& package);
|
||||
void _AdoptPackage(const PackageInfoRef& package);
|
||||
void _ClearPackage();
|
||||
|
||||
void _InitDummyModel();
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <Catalog.h>
|
||||
|
||||
|
||||
@ -24,7 +25,7 @@ PackageFilter::~PackageFilter()
|
||||
|
||||
class AnyFilter : public PackageFilter {
|
||||
public:
|
||||
virtual bool AcceptsPackage(const PackageInfo& package) const
|
||||
virtual bool AcceptsPackage(const PackageInfoRef& package) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -39,7 +40,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool AcceptsPackage(const PackageInfo& package) const
|
||||
virtual bool AcceptsPackage(const PackageInfoRef& package) const
|
||||
{
|
||||
// TODO: Maybe a PackageInfo ought to know the Depot it came from?
|
||||
// But right now the same package could theoretically be provided
|
||||
@ -68,9 +69,11 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool AcceptsPackage(const PackageInfo& package) const
|
||||
virtual bool AcceptsPackage(const PackageInfoRef& package) const
|
||||
{
|
||||
const CategoryList& categories = package.Categories();
|
||||
if (package.Get() == NULL)
|
||||
return false;
|
||||
const CategoryList& categories = package->Categories();
|
||||
for (int i = categories.CountItems() - 1; i >= 0; i--) {
|
||||
const CategoryRef& category = categories.ItemAtFast(i);
|
||||
if (category.Get() == NULL)
|
||||
@ -94,7 +97,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool AcceptsPackage(const PackageInfo& package) const
|
||||
virtual bool AcceptsPackage(const PackageInfoRef& package) const
|
||||
{
|
||||
return fPackageList.Contains(package);
|
||||
}
|
||||
@ -114,7 +117,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool AcceptsPackage(const PackageInfo& package) const
|
||||
virtual bool AcceptsPackage(const PackageInfoRef& package) const
|
||||
{
|
||||
return fPackageListA.Contains(package)
|
||||
|| fPackageListB.Contains(package);
|
||||
@ -146,15 +149,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool AcceptsPackage(const PackageInfo& package) const
|
||||
virtual bool AcceptsPackage(const PackageInfoRef& package) const
|
||||
{
|
||||
if (package.Get() == NULL)
|
||||
return false;
|
||||
// Every search term must be found in one of the package texts
|
||||
for (int32 i = fSearchTerms.CountItems() - 1; i >= 0; i--) {
|
||||
const BString& term = fSearchTerms.ItemAtFast(i);
|
||||
if (!_TextContains(package.Title(), term)
|
||||
&& !_TextContains(package.Publisher().Name(), term)
|
||||
&& !_TextContains(package.ShortDescription(), term)
|
||||
&& !_TextContains(package.FullDescription(), term)) {
|
||||
if (!_TextContains(package->Title(), term)
|
||||
&& !_TextContains(package->Publisher().Name(), term)
|
||||
&& !_TextContains(package->ShortDescription(), term)
|
||||
&& !_TextContains(package->FullDescription(), term)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -263,7 +268,7 @@ Model::CreatePackageList() const
|
||||
const PackageList& packages = depot.Packages();
|
||||
|
||||
for (int32 j = 0; j < packages.CountItems(); j++) {
|
||||
const PackageInfo& package = packages.ItemAtFast(j);
|
||||
const PackageInfoRef& package = packages.ItemAtFast(j);
|
||||
if (fCategoryFilter->AcceptsPackage(package)
|
||||
&& fSearchTermsFilter->AcceptsPackage(package)) {
|
||||
resultList.Add(package);
|
||||
@ -283,7 +288,7 @@ Model::AddDepot(const DepotInfo& depot)
|
||||
|
||||
|
||||
void
|
||||
Model::SetPackageState(const PackageInfo& package, PackageState state)
|
||||
Model::SetPackageState(const PackageInfoRef& package, PackageState state)
|
||||
{
|
||||
switch (state) {
|
||||
default:
|
||||
@ -362,3 +367,86 @@ Model::SetSearchTerms(const BString& searchTerms)
|
||||
fSearchTermsFilter.SetTo(filter, true);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - information retrival
|
||||
|
||||
|
||||
void
|
||||
Model::PopulatePackage(const PackageInfoRef& package)
|
||||
{
|
||||
if (fPopulatedPackages.Contains(package))
|
||||
return;
|
||||
|
||||
BAutolock _(&fLock);
|
||||
|
||||
// TODO: Replace with actual backend that retrieves package extra
|
||||
// information and user-contributed package information.
|
||||
|
||||
// TODO: There should probably also be a way to "unpopulate" the
|
||||
// package information. Maybe a cache of populated packages, so that
|
||||
// packages loose their extra information after a certain amount of
|
||||
// time when they have not been accessed/displayed in the UI. Otherwise
|
||||
// HaikuDepot will consume more and more resources in the packages.
|
||||
// Especially screen-shots will be a problem eventually.
|
||||
|
||||
// TODO: Simulate a delay in retrieving this info, and do that on
|
||||
// a separate thread.
|
||||
|
||||
fPopulatedPackages.Add(package);
|
||||
|
||||
if (package->Title() == "WonderBrush") {
|
||||
|
||||
package->AddUserRating(
|
||||
UserRating(UserInfo("humdinger"), 4.5f,
|
||||
"Awesome!", "en", "2.1.2", 0, 0)
|
||||
);
|
||||
package->AddUserRating(
|
||||
UserRating(UserInfo("bonefish"), 5.0f,
|
||||
"The best!", "en", "2.1.2", 3, 1)
|
||||
);
|
||||
package->AddScreenshot(
|
||||
BitmapRef(new SharedBitmap(603), true));
|
||||
|
||||
} else if (package->Title() == "Paladin") {
|
||||
|
||||
package->AddUserRating(
|
||||
UserRating(UserInfo("stippi"), 3.5f,
|
||||
"Could be more integrated from the sounds of it.",
|
||||
"en", "1.2.0", 0, 1)
|
||||
);
|
||||
package->AddUserRating(
|
||||
UserRating(UserInfo("mmadia"), 5.0f,
|
||||
"It rocks! Give a try",
|
||||
"en", "1.1.0", 1, 0)
|
||||
);
|
||||
package->AddUserRating(
|
||||
UserRating(UserInfo("bonefish"), 2.0f,
|
||||
"It just needs to use my jam-rewrite 'ham' and it will be great.",
|
||||
"en", "1.1.0", 3, 1)
|
||||
);
|
||||
package->AddScreenshot(
|
||||
BitmapRef(new SharedBitmap(605), true));
|
||||
|
||||
} else if (package->Title() == "Sequitur") {
|
||||
|
||||
package->AddUserRating(
|
||||
UserRating(UserInfo("pete"), 4.5f,
|
||||
"I can weave a web of sound! And it connects to PatchBay. Check "
|
||||
"it out, I can wholeheartly recommend this app!! This rating "
|
||||
"comment is of course only so long, because the new TextView "
|
||||
"layout needs some testing. Oh, and did I mention it works with "
|
||||
"custom installed sound fonts? Reading through this comment I find "
|
||||
"that I did not until now. Hopefully there are enough lines now to "
|
||||
"please the programmer with the text layouting and scrolling of "
|
||||
"long ratings!", "en", "2.1.0", 4, 1)
|
||||
);
|
||||
package->AddUserRating(
|
||||
UserRating(UserInfo("stippi"), 3.5f,
|
||||
"It seems very capable. Still runs fine on Haiku. The interface "
|
||||
"is composed of many small, hard to click items. But you can "
|
||||
"configure a tool for each mouse button, which is great for the "
|
||||
"work flow.", "en", "2.1.0", 2, 1)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
#include <Locker.h>
|
||||
|
||||
#include "PackageInfo.h"
|
||||
|
||||
@ -14,7 +15,7 @@ public:
|
||||
virtual ~PackageFilter();
|
||||
|
||||
virtual bool AcceptsPackage(
|
||||
const PackageInfo& package) const = 0;
|
||||
const PackageInfoRef& package) const = 0;
|
||||
};
|
||||
|
||||
typedef BReference<PackageFilter> PackageFilterRef;
|
||||
@ -24,6 +25,9 @@ class Model {
|
||||
public:
|
||||
Model();
|
||||
|
||||
BLocker* Lock()
|
||||
{ return &fLock; }
|
||||
|
||||
// !Returns new PackageInfoList from current parameters
|
||||
PackageList CreatePackageList() const;
|
||||
|
||||
@ -55,7 +59,7 @@ public:
|
||||
{ return fProgressCategories; }
|
||||
|
||||
void SetPackageState(
|
||||
const PackageInfo& package,
|
||||
const PackageInfoRef& package,
|
||||
PackageState state);
|
||||
|
||||
// Configure PackageFilters
|
||||
@ -63,7 +67,12 @@ public:
|
||||
void SetDepot(const BString& depot);
|
||||
void SetSearchTerms(const BString& searchTerms);
|
||||
|
||||
// Retrieve package information
|
||||
void PopulatePackage(const PackageInfoRef& package);
|
||||
|
||||
private:
|
||||
BLocker fLock;
|
||||
|
||||
DepotList fDepots;
|
||||
|
||||
CategoryRef fCategoryAudio;
|
||||
@ -84,6 +93,7 @@ private:
|
||||
PackageList fUninstalledPackages;
|
||||
PackageList fDownloadingPackages;
|
||||
PackageList fUpdateablePackages;
|
||||
PackageList fPopulatedPackages;
|
||||
|
||||
PackageFilterRef fCategoryFilter;
|
||||
BString fDepotFilter;
|
||||
|
@ -535,7 +535,12 @@ PackageInfo::AddCategory(const CategoryRef& category)
|
||||
bool
|
||||
PackageInfo::AddUserRating(const UserRating& rating)
|
||||
{
|
||||
return fUserRatings.Add(rating);
|
||||
if (!fUserRatings.Add(rating))
|
||||
return false;
|
||||
|
||||
_NotifyListeners(PKG_CHANGED_RATINGS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -584,7 +589,50 @@ PackageInfo::CalculateRatingSummary() const
|
||||
bool
|
||||
PackageInfo::AddScreenshot(const BitmapRef& screenshot)
|
||||
{
|
||||
return fScreenshots.Add(screenshot);
|
||||
if (!fScreenshots.Add(screenshot))
|
||||
return false;
|
||||
|
||||
_NotifyListeners(PKG_CHANGED_SCREENSHOTS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageInfo::AddListener(const PackageInfoListenerRef& listener)
|
||||
{
|
||||
return fListeners.Add(listener);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageInfo::RemoveListener(const PackageInfoListenerRef& listener)
|
||||
{
|
||||
fListeners.Remove(listener);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageInfo::_NotifyListeners(uint32 changes)
|
||||
{
|
||||
int count = fListeners.CountItems();
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
// Clone list to avoid listeners detaching themselves in notifications
|
||||
// to screw up the list while iterating it.
|
||||
PackageListenerList listeners(fListeners);
|
||||
// Check if it worked:
|
||||
if (listeners.CountItems () != count)
|
||||
return;
|
||||
|
||||
PackageInfoEvent event(PackageInfoRef(this), changes);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
const PackageInfoListenerRef& listener = listeners.ItemAtFast(i);
|
||||
if (listener.Get() != NULL)
|
||||
listener->PackageChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -640,7 +688,7 @@ DepotInfo::operator!=(const DepotInfo& other) const
|
||||
|
||||
|
||||
bool
|
||||
DepotInfo::AddPackage(const PackageInfo& package)
|
||||
DepotInfo::AddPackage(const PackageInfoRef& package)
|
||||
{
|
||||
return fPackages.Add(package);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <String.h>
|
||||
|
||||
#include "List.h"
|
||||
#include "PackageInfoListener.h"
|
||||
|
||||
|
||||
class BBitmap;
|
||||
@ -181,7 +182,10 @@ typedef BReference<PackageCategory> CategoryRef;
|
||||
typedef List<CategoryRef, false> CategoryList;
|
||||
|
||||
|
||||
class PackageInfo {
|
||||
typedef List<PackageInfoListenerRef, false, 2> PackageListenerList;
|
||||
|
||||
|
||||
class PackageInfo : public BReferenceable {
|
||||
public:
|
||||
PackageInfo();
|
||||
PackageInfo(const BitmapRef& icon,
|
||||
@ -225,6 +229,14 @@ public:
|
||||
const BitmapList& Screenshots() const
|
||||
{ return fScreenshots; }
|
||||
|
||||
bool AddListener(
|
||||
const PackageInfoListenerRef& listener);
|
||||
void RemoveListener(
|
||||
const PackageInfoListenerRef& listener);
|
||||
|
||||
private:
|
||||
void _NotifyListeners(uint32 changes);
|
||||
|
||||
private:
|
||||
BitmapRef fIcon;
|
||||
BString fTitle;
|
||||
@ -236,10 +248,14 @@ private:
|
||||
CategoryList fCategories;
|
||||
UserRatingList fUserRatings;
|
||||
BitmapList fScreenshots;
|
||||
PackageListenerList fListeners;
|
||||
};
|
||||
|
||||
|
||||
typedef List<PackageInfo, false> PackageList;
|
||||
typedef BReference<PackageInfo> PackageInfoRef;
|
||||
|
||||
|
||||
typedef List<PackageInfoRef, false> PackageList;
|
||||
|
||||
|
||||
enum PackageState {
|
||||
@ -266,7 +282,7 @@ public:
|
||||
const PackageList& Packages() const
|
||||
{ return fPackages; }
|
||||
|
||||
bool AddPackage(const PackageInfo& package);
|
||||
bool AddPackage(const PackageInfoRef& package);
|
||||
|
||||
private:
|
||||
BString fName;
|
||||
|
86
src/apps/haiku-depot/PackageInfoListener.cpp
Normal file
86
src/apps/haiku-depot/PackageInfoListener.cpp
Normal file
@ -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()
|
||||
{
|
||||
}
|
61
src/apps/haiku-depot/PackageInfoListener.h
Normal file
61
src/apps/haiku-depot/PackageInfoListener.h
Normal file
@ -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
|
@ -8,6 +8,7 @@
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Button.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
|
||||
|
||||
|
||||
PackageInfoView::PackageInfoView(PackageManager* packageManager)
|
||||
PackageInfoView::PackageInfoView(BLocker* modelLock,
|
||||
PackageManager* packageManager)
|
||||
:
|
||||
BGroupView("package info view", B_VERTICAL)
|
||||
BGroupView("package info view", B_VERTICAL),
|
||||
fModelLock(modelLock),
|
||||
fPackageListener(new(std::nothrow) Listener(this))
|
||||
{
|
||||
fTitleView = new TitleView();
|
||||
fPackageActionView = new PackageActionView(packageManager);
|
||||
@ -1150,6 +1216,8 @@ PackageInfoView::PackageInfoView(PackageManager* packageManager)
|
||||
|
||||
PackageInfoView::~PackageInfoView()
|
||||
{
|
||||
fPackageListener->SetPackage(PackageInfoRef(NULL));
|
||||
delete fPackageListener;
|
||||
}
|
||||
|
||||
|
||||
@ -1163,6 +1231,35 @@ void
|
||||
PackageInfoView::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_UPDATE_PACKAGE:
|
||||
{
|
||||
if (fPackageListener->Package().Get() == NULL)
|
||||
break;
|
||||
|
||||
BString title;
|
||||
uint32 changes;
|
||||
if (message->FindString("title", &title) != B_OK
|
||||
|| message->FindUInt32("changes", &changes) != B_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
const PackageInfo& package = *fPackageListener->Package().Get();
|
||||
if (package.Title() != title)
|
||||
break;
|
||||
|
||||
BAutolock _(fModelLock);
|
||||
|
||||
if ((changes & PKG_CHANGED_DESCRIPTION) != 0
|
||||
|| (changes & PKG_CHANGED_SCREENSHOTS) != 0) {
|
||||
fTitleView->SetPackage(package);
|
||||
}
|
||||
|
||||
if ((changes & PKG_CHANGED_RATINGS) != 0) {
|
||||
fPagesView->SetPackage(package);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BGroupView::MessageReceived(message);
|
||||
break;
|
||||
@ -1171,14 +1268,20 @@ PackageInfoView::MessageReceived(BMessage* message)
|
||||
|
||||
|
||||
void
|
||||
PackageInfoView::SetPackage(const PackageInfo& package)
|
||||
PackageInfoView::SetPackage(const PackageInfoRef& packageRef)
|
||||
{
|
||||
BAutolock _(fModelLock);
|
||||
|
||||
const PackageInfo& package = *packageRef.Get();
|
||||
|
||||
fTitleView->SetPackage(package);
|
||||
fPackageActionView->SetPackage(package);
|
||||
fPagesView->SetPackage(package);
|
||||
|
||||
if (fPagesView->IsHidden(fPagesView))
|
||||
fPagesView->Show();
|
||||
|
||||
fPackageListener->SetPackage(packageRef);
|
||||
}
|
||||
|
||||
|
||||
@ -1191,5 +1294,9 @@ PackageInfoView::Clear()
|
||||
|
||||
if (!fPagesView->IsHidden(fPagesView))
|
||||
fPagesView->Hide();
|
||||
|
||||
BAutolock _(fModelLock);
|
||||
|
||||
fPackageListener->SetPackage(PackageInfoRef(NULL));
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,10 @@
|
||||
#include <GroupView.h>
|
||||
|
||||
#include "PackageInfo.h"
|
||||
#include "PackageInfoListener.h"
|
||||
|
||||
|
||||
class BLocker;
|
||||
class TitleView;
|
||||
class PackageActionView;
|
||||
class PackageManager;
|
||||
@ -23,19 +25,27 @@ enum {
|
||||
|
||||
class PackageInfoView : public BGroupView {
|
||||
public:
|
||||
PackageInfoView(PackageManager* packageManager);
|
||||
PackageInfoView(BLocker* modelLock,
|
||||
PackageManager* packageManager);
|
||||
virtual ~PackageInfoView();
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
void SetPackage(const PackageInfo& package);
|
||||
void SetPackage(const PackageInfoRef& package);
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
class Listener;
|
||||
|
||||
private:
|
||||
BLocker* fModelLock;
|
||||
|
||||
TitleView* fTitleView;
|
||||
PackageActionView* fPackageActionView;
|
||||
PagesView* fPagesView;
|
||||
|
||||
Listener* fPackageListener;
|
||||
};
|
||||
|
||||
#endif // PACKAGE_INFO_VIEW_H
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <Catalog.h>
|
||||
#include <ScrollBar.h>
|
||||
#include <Window.h>
|
||||
@ -80,13 +81,58 @@ private:
|
||||
class PackageRow : public BRow {
|
||||
typedef BRow Inherited;
|
||||
public:
|
||||
PackageRow(const PackageInfo& package);
|
||||
PackageRow(const PackageInfoRef& package,
|
||||
PackageListener* listener);
|
||||
virtual ~PackageRow();
|
||||
|
||||
const PackageInfo& Package() const
|
||||
const PackageInfoRef& Package() const
|
||||
{ return fPackage; }
|
||||
|
||||
void UpdateRating();
|
||||
|
||||
private:
|
||||
PackageInfo fPackage;
|
||||
PackageInfoRef fPackage;
|
||||
PackageInfoListenerRef fPackageListener;
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
MSG_UPDATE_PACKAGE = 'updp'
|
||||
};
|
||||
|
||||
|
||||
class PackageListener : public PackageInfoListener {
|
||||
public:
|
||||
PackageListener(PackageListView* view)
|
||||
:
|
||||
fView(view)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~PackageListener()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void PackageChanged(const PackageInfoEvent& event)
|
||||
{
|
||||
if ((event.Changes() & PKG_CHANGED_RATINGS) == 0)
|
||||
return;
|
||||
|
||||
BMessenger messenger(fView);
|
||||
if (!messenger.IsValid())
|
||||
return;
|
||||
|
||||
const PackageInfo& package = *event.Package().Get();
|
||||
|
||||
BMessage message(MSG_UPDATE_PACKAGE);
|
||||
message.AddString("title", package.Title());
|
||||
message.AddUInt32("changes", event.Changes());
|
||||
|
||||
messenger.SendMessage(&message);
|
||||
}
|
||||
|
||||
private:
|
||||
PackageListView* fView;
|
||||
};
|
||||
|
||||
|
||||
@ -374,11 +420,18 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
PackageRow::PackageRow(const PackageInfo& package)
|
||||
PackageRow::PackageRow(const PackageInfoRef& packageRef,
|
||||
PackageListener* packageListener)
|
||||
:
|
||||
Inherited(ceilf(be_plain_font->Size() * 1.8f)),
|
||||
fPackage(package)
|
||||
fPackage(packageRef),
|
||||
fPackageListener(packageListener)
|
||||
{
|
||||
if (packageRef.Get() == NULL)
|
||||
return;
|
||||
|
||||
PackageInfo& package = *packageRef.Get();
|
||||
|
||||
// Package icon and title
|
||||
// NOTE: The icon BBitmap is referenced by the fPackage member.
|
||||
const BBitmap* icon = NULL;
|
||||
@ -387,8 +440,7 @@ PackageRow::PackageRow(const PackageInfo& package)
|
||||
SetField(new BBitmapStringField(icon, package.Title()), kTitleColumn);
|
||||
|
||||
// Rating
|
||||
RatingSummary summary = package.CalculateRatingSummary();
|
||||
SetField(new RatingField(summary.averageRating), kRatingColumn);
|
||||
UpdateRating();
|
||||
|
||||
// Description
|
||||
SetField(new BStringField(package.ShortDescription()), kDescriptionColumn);
|
||||
@ -400,6 +452,25 @@ PackageRow::PackageRow(const PackageInfo& package)
|
||||
// Status
|
||||
// TODO: Fetch info about installed/deactivated/unintalled/...
|
||||
SetField(new BStringField("n/a"), kStatusColumn);
|
||||
|
||||
package.AddListener(fPackageListener);
|
||||
}
|
||||
|
||||
|
||||
PackageRow::~PackageRow()
|
||||
{
|
||||
if (fPackage.Get() != NULL)
|
||||
fPackage->RemoveListener(fPackageListener);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageRow::UpdateRating()
|
||||
{
|
||||
if (fPackage.Get() == NULL)
|
||||
return;
|
||||
RatingSummary summary = fPackage->CalculateRatingSummary();
|
||||
SetField(new RatingField(summary.averageRating), kRatingColumn);
|
||||
}
|
||||
|
||||
|
||||
@ -487,9 +558,11 @@ private:
|
||||
// #pragma mark - PackageListView
|
||||
|
||||
|
||||
PackageListView::PackageListView()
|
||||
PackageListView::PackageListView(BLocker* modelLock)
|
||||
:
|
||||
BColumnListView("package list view", 0, B_FANCY_BORDER, true)
|
||||
BColumnListView("package list view", 0, B_FANCY_BORDER, true),
|
||||
fModelLock(modelLock),
|
||||
fPackageListener(new(std::nothrow) PackageListener(this))
|
||||
{
|
||||
AddColumn(new PackageColumn(B_TRANSLATE("Name"), 150, 50, 300,
|
||||
B_TRUNCATE_MIDDLE), kTitleColumn);
|
||||
@ -511,6 +584,8 @@ PackageListView::PackageListView()
|
||||
|
||||
PackageListView::~PackageListView()
|
||||
{
|
||||
Clear();
|
||||
delete fPackageListener;
|
||||
}
|
||||
|
||||
|
||||
@ -525,6 +600,27 @@ void
|
||||
PackageListView::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_UPDATE_PACKAGE:
|
||||
{
|
||||
BString title;
|
||||
uint32 changes;
|
||||
if (message->FindString("title", &title) != B_OK
|
||||
|| message->FindUInt32("changes", &changes) != B_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((changes & PKG_CHANGED_RATINGS) == 0)
|
||||
break;
|
||||
|
||||
BAutolock _(fModelLock);
|
||||
|
||||
PackageRow* row = _FindRow(title);
|
||||
if (row != NULL)
|
||||
row->UpdateRating();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BColumnListView::MessageReceived(message);
|
||||
break;
|
||||
@ -539,21 +635,16 @@ PackageListView::SelectionChanged()
|
||||
|
||||
BMessage message(MSG_PACKAGE_SELECTED);
|
||||
|
||||
BRow* selected = CurrentSelection();
|
||||
|
||||
// TODO: Wrong index, its the visible one (i.e. sorted)!
|
||||
// Solve by putting an ID for the package in the message instead.
|
||||
int32 index = -1;
|
||||
PackageRow* selected = dynamic_cast<PackageRow*>(CurrentSelection());
|
||||
if (selected != NULL)
|
||||
index = IndexOf(selected);
|
||||
message.AddInt32("index", index);
|
||||
message.AddString("title", selected->Package()->Title());
|
||||
|
||||
Window()->PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageListView::AddPackage(const PackageInfo& package)
|
||||
PackageListView::AddPackage(const PackageInfoRef& package)
|
||||
{
|
||||
PackageRow* packageRow = _FindRow(package);
|
||||
|
||||
@ -561,8 +652,10 @@ PackageListView::AddPackage(const PackageInfo& package)
|
||||
if (packageRow != NULL)
|
||||
return;
|
||||
|
||||
BAutolock _(fModelLock);
|
||||
|
||||
// create the row for this package
|
||||
packageRow = new PackageRow(package);
|
||||
packageRow = new PackageRow(package, fPackageListener);
|
||||
|
||||
// add the row, parent may be NULL (add at top level)
|
||||
AddRow(packageRow);
|
||||
@ -575,7 +668,7 @@ PackageListView::AddPackage(const PackageInfo& package)
|
||||
|
||||
|
||||
PackageRow*
|
||||
PackageListView::_FindRow(const PackageInfo& package, PackageRow* parent)
|
||||
PackageListView::_FindRow(const PackageInfoRef& package, PackageRow* parent)
|
||||
{
|
||||
for (int32 i = CountRows(parent) - 1; i >= 0; i--) {
|
||||
PackageRow* row = dynamic_cast<PackageRow*>(RowAt(i, parent));
|
||||
@ -592,3 +685,24 @@ PackageListView::_FindRow(const PackageInfo& package, PackageRow* parent)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PackageRow*
|
||||
PackageListView::_FindRow(const BString& packageTitle, PackageRow* parent)
|
||||
{
|
||||
for (int32 i = CountRows(parent) - 1; i >= 0; i--) {
|
||||
PackageRow* row = dynamic_cast<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;
|
||||
}
|
||||
|
||||
|
@ -8,11 +8,13 @@
|
||||
|
||||
#include <ColumnListView.h>
|
||||
#include <ColumnTypes.h>
|
||||
#include <Locker.h>
|
||||
|
||||
#include "PackageInfo.h"
|
||||
|
||||
|
||||
class PackageRow;
|
||||
class PackageListener;
|
||||
|
||||
enum {
|
||||
MSG_PACKAGE_SELECTED = 'pkgs',
|
||||
@ -21,7 +23,7 @@ enum {
|
||||
|
||||
class PackageListView : public BColumnListView {
|
||||
public:
|
||||
PackageListView();
|
||||
PackageListView(BLocker* modelLock);
|
||||
virtual ~PackageListView();
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
@ -29,15 +31,20 @@ public:
|
||||
|
||||
virtual void SelectionChanged();
|
||||
|
||||
void AddPackage(const PackageInfo& package);
|
||||
void AddPackage(const PackageInfoRef& package);
|
||||
|
||||
private:
|
||||
PackageRow* _FindRow(const PackageInfo& package,
|
||||
PackageRow* _FindRow(const PackageInfoRef& package,
|
||||
PackageRow* parent = NULL);
|
||||
PackageRow* _FindRow(const BString& packageTitle,
|
||||
PackageRow* parent = NULL);
|
||||
|
||||
private:
|
||||
class ItemCountView;
|
||||
|
||||
|
||||
BLocker* fModelLock;
|
||||
ItemCountView* fItemCountView;
|
||||
PackageListener* fPackageListener;
|
||||
};
|
||||
|
||||
#endif // PACKAGE_LIST_VIEW_H
|
||||
|
3
src/bin/makebootable/platform/u-boot/Jamfile
Normal file
3
src/bin/makebootable/platform/u-boot/Jamfile
Normal file
@ -0,0 +1,3 @@
|
||||
SubDir HAIKU_TOP src bin makebootable platform u-boot ;
|
||||
|
||||
BinCommand makebootable : makebootable.cpp ;
|
6
src/bin/makebootable/platform/u-boot/makebootable.cpp
Normal file
6
src/bin/makebootable/platform/u-boot/makebootable.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
int
|
||||
main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ static const media_type kMediaTypes[] = {
|
||||
{ IFM_100_TX, "100baseTX", "100 MBit, 100BASE-TX" },
|
||||
{ IFM_1000_T, "1000baseT", "1 GBit, 1000BASE-T" },
|
||||
{ IFM_1000_SX, "1000baseSX", "1 GBit, 1000BASE-SX" },
|
||||
{ IFM_10G_T, "10GbaseT", "10 GBit, 10GBASE-T" },
|
||||
{ -1, NULL, NULL }
|
||||
},
|
||||
{
|
||||
@ -1012,4 +1013,3 @@ main(int argc, char** argv)
|
||||
list_interfaces(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -12,3 +12,5 @@ resource(5, "META:EXTENS") message(234) {
|
||||
"extensions" = "MP3",
|
||||
"type" = "audio/mpeg"
|
||||
};
|
||||
|
||||
resource(6, "META:SNIFF_RULE") "0.50 (0xfffb|0xfffa|\"ID3\")";
|
||||
|
@ -500,9 +500,7 @@ BRow::SetField(BField* field, int32 logicalFieldIndex)
|
||||
|
||||
if (NULL != fList) {
|
||||
ValidateField(field, logicalFieldIndex);
|
||||
BRect inv;
|
||||
fList->GetRowRect(this, &inv);
|
||||
fList->Invalidate(inv);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
fFields.AddItem(field, logicalFieldIndex);
|
||||
@ -530,6 +528,14 @@ BRow::IsSelected() const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRow::Invalidate()
|
||||
{
|
||||
if (fList != NULL)
|
||||
fList->InvalidateRow(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRow::ValidateFields() const
|
||||
{
|
||||
@ -1340,6 +1346,15 @@ BColumnListView::Clear()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BColumnListView::InvalidateRow(BRow* row)
|
||||
{
|
||||
BRect updateRect;
|
||||
GetRowRect(row, &updateRect);
|
||||
fOutlineView->Invalidate(updateRect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BColumnListView::SetFont(const BFont* font, uint32 mask)
|
||||
{
|
||||
|
@ -1037,10 +1037,13 @@ BListView::ScrollToSelection()
|
||||
if (Bounds().Contains(itemFrame))
|
||||
return;
|
||||
|
||||
if (itemFrame.top < Bounds().top)
|
||||
ScrollTo(itemFrame.left, itemFrame.top);
|
||||
else
|
||||
ScrollTo(itemFrame.left, itemFrame.bottom - Bounds().Height());
|
||||
float scrollPos = itemFrame.top < Bounds().top ?
|
||||
itemFrame.top : itemFrame.bottom - Bounds().Height();
|
||||
|
||||
if (itemFrame.top - scrollPos < Bounds().top)
|
||||
scrollPos = itemFrame.top;
|
||||
|
||||
ScrollTo(itemFrame.left, scrollPos);
|
||||
}
|
||||
|
||||
|
||||
|
@ -583,8 +583,6 @@ ModulesView::DetachedFromWindow()
|
||||
void
|
||||
ModulesView::AttachedToWindow()
|
||||
{
|
||||
PopulateScreenSaverList();
|
||||
|
||||
fScreenSaversListView->SetTarget(this);
|
||||
fTestButton->SetTarget(this);
|
||||
fAddButton->SetTarget(this);
|
||||
@ -594,8 +592,7 @@ ModulesView::AttachedToWindow()
|
||||
void
|
||||
ModulesView::AllAttached()
|
||||
{
|
||||
fScreenSaversListView->ScrollToSelection();
|
||||
// This only works after the list view is attached
|
||||
PopulateScreenSaverList();
|
||||
fScreenSaversListView->Invoke(new BMessage(kMsgSaverSelected));
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ actions BuildUImageScript1
|
||||
rule BuildUBootSDImage image : files
|
||||
{
|
||||
Depends $(image) : $(files) ;
|
||||
SDIMAGE_BLOCK_SIZE on $(image) = 1M ;
|
||||
SDIMAGE_BLOCK_SIZE on $(image) = 1048576 ; # 1M
|
||||
SDIMAGE_SIZE on $(image) = $(HAIKU_BOARD_SDIMAGE_SIZE) ;
|
||||
SDIMAGE_FDISK on $(image) = $(HOST_SFDISK) ;
|
||||
SDIMAGE_FDISK_SCRIPT on $(image) =
|
||||
|
@ -5,10 +5,12 @@
|
||||
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <boot/platform.h>
|
||||
|
||||
#include <boot/disk_identifier.h>
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/stdio.h>
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <boot/stdio.h>
|
||||
|
||||
#define TRACE_DEVICES
|
||||
#ifdef TRACE_DEVICES
|
||||
@ -73,6 +75,18 @@ platform_add_block_devices(stage2_args *args, NodeList *devicesList)
|
||||
status_t
|
||||
platform_register_boot_device(Node *device)
|
||||
{
|
||||
TRACE("platform_register_boot_device\n");
|
||||
disk_identifier disk_ident;
|
||||
disk_ident.bus_type = UNKNOWN_BUS;
|
||||
disk_ident.device_type = UNKNOWN_DEVICE;
|
||||
disk_ident.device.unknown.size = device->Size();
|
||||
|
||||
for (int32 i = 0; i < NUM_DISK_CHECK_SUMS; i++) {
|
||||
disk_ident.device.unknown.check_sums[i].offset = -1;
|
||||
disk_ident.device.unknown.check_sums[i].sum = 0;
|
||||
}
|
||||
|
||||
gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE,
|
||||
&disk_ident, sizeof(disk_ident));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ image_multi_getimg(struct image_header *image, uint32 idx, uint32 *data, uint32
|
||||
*size = ntohl(sizes[i]);
|
||||
return true;
|
||||
}
|
||||
base += ntohl(sizes[i]);
|
||||
base += (ntohl(sizes[i]) + 3) & ~3;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -227,8 +227,8 @@ FUNCTION(arch_debug_call_with_fault_handler):
|
||||
// Set fault handler address, and fault handler stack pointer address. We
|
||||
// don't need to save the previous values, since that's done by the caller.
|
||||
ldr r4, =1f
|
||||
str r4, [ r0, #CPU_ENT_fault_handler ]
|
||||
str sp, [ r0, #CPU_ENT_fault_handler_stack_pointer ]
|
||||
str r4, [r0, #CPU_ENT_fault_handler]
|
||||
str sp, [r0, #CPU_ENT_fault_handler_stack_pointer]
|
||||
mov r4, r1
|
||||
|
||||
// call the function
|
||||
|
@ -35,35 +35,63 @@
|
||||
#define PXA_OSSR 0x05
|
||||
#define PXA_OIER 0x07
|
||||
#define PXA_OSCR4 0x10
|
||||
#define PXA_OSCR5 0x11
|
||||
#define PXA_OSMR4 0x20
|
||||
#define PXA_OSMR5 0x21
|
||||
#define PXA_OMCR4 0x30
|
||||
#define PXA_OMCR5 0x31
|
||||
|
||||
#define PXA_RES_S (3 << 0)
|
||||
#define PXA_RES_MS (1 << 1)
|
||||
#define PXA_RES_US (1 << 2)
|
||||
|
||||
static area_id sPxaTimersArea;
|
||||
static uint32 *sPxaTimersBase;
|
||||
#define US2S(bt) ((bt) / 1000000ULL)
|
||||
#define US2MS(bt) ((bt) / 1000ULL)
|
||||
|
||||
static area_id sPxaTimersArea = B_ERROR;
|
||||
static uint32 *sPxaTimersBase = NULL;
|
||||
static bigtime_t sSystemTime = 0;
|
||||
|
||||
static int32
|
||||
pxa_timer_interrupt(void *data)
|
||||
{
|
||||
int32 ret = timer_interrupt();
|
||||
sPxaTimersBase[PXA_OSSR] |= (1 << 4);
|
||||
if (sPxaTimersBase[PXA_OSSR] & (1 << 4)) {
|
||||
sPxaTimersBase[PXA_OSSR] |= (1 << 4);
|
||||
return timer_interrupt();
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (sPxaTimersBase[PXA_OSSR] & (1 << 5)) {
|
||||
sPxaTimersBase[PXA_OSSR] |= (1 << 5);
|
||||
sSystemTime += UINT_MAX + 1ULL;
|
||||
}
|
||||
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arch_timer_set_hardware_timer(bigtime_t timeout)
|
||||
{
|
||||
TRACE(("arch_timer_set_hardware_timer(%lld)\n", timeout));
|
||||
uint32 val = timeout & UINT_MAX;
|
||||
uint32 res = PXA_RES_US;
|
||||
|
||||
if (sPxaTimersBase) {
|
||||
sPxaTimersBase[PXA_OIER] |= (1 << 4);
|
||||
sPxaTimersBase[PXA_OMCR4] = 4; // set to exactly single milisecond resolution
|
||||
sPxaTimersBase[PXA_OSMR4] = timeout;
|
||||
sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again
|
||||
if (timeout & ~UINT_MAX) {
|
||||
// Does not fit, so scale resolution down to milliseconds
|
||||
if (US2MS(timeout) & ~UINT_MAX) {
|
||||
// Still does not fit, scale down to seconds as last ditch attempt
|
||||
val = US2S(timeout) & UINT_MAX;
|
||||
res = PXA_RES_S;
|
||||
} else {
|
||||
// Fits in millisecond resolution
|
||||
val = US2MS(timeout) & UINT_MAX;
|
||||
res = PXA_RES_MS;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE(("arch_timer_set_hardware_timer(val=%lu, res=%lu)\n", val, res));
|
||||
sPxaTimersBase[PXA_OIER] |= (1 << 4);
|
||||
sPxaTimersBase[PXA_OMCR4] = res;
|
||||
sPxaTimersBase[PXA_OSMR4] = val;
|
||||
sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again
|
||||
}
|
||||
|
||||
|
||||
@ -72,13 +100,10 @@ arch_timer_clear_hardware_timer()
|
||||
{
|
||||
TRACE(("arch_timer_clear_hardware_timer\n"));
|
||||
|
||||
if (sPxaTimersBase) {
|
||||
sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer
|
||||
sPxaTimersBase[PXA_OIER] &= ~(4 << 1);
|
||||
}
|
||||
sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer
|
||||
sPxaTimersBase[PXA_OIER] &= ~(1 << 4);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_init_timer(kernel_args *args)
|
||||
{
|
||||
@ -88,9 +113,20 @@ arch_init_timer(kernel_args *args)
|
||||
if (sPxaTimersArea < 0)
|
||||
return sPxaTimersArea;
|
||||
|
||||
sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer
|
||||
sPxaTimersBase[PXA_OIER] |= (1 << 5); // enable timekeeping timer
|
||||
sPxaTimersBase[PXA_OMCR5] = PXA_RES_US | (1 << 7);
|
||||
sPxaTimersBase[PXA_OSMR5] = UINT_MAX;
|
||||
sPxaTimersBase[PXA_OSCR5] = 0;
|
||||
|
||||
install_io_interrupt_handler(PXA_TIMERS_INTERRUPT, &pxa_timer_interrupt, NULL, 0);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
{
|
||||
return (sPxaTimersBase != NULL) ?
|
||||
sSystemTime + sPxaTimersBase[PXA_OSCR5] :
|
||||
0ULL;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -60,10 +60,8 @@ X86PagingMethod64Bit::Init(kernel_args* args,
|
||||
fKernelVirtualPML4 = (uint64*)(addr_t)args->arch_args.vir_pgdir;
|
||||
|
||||
// if availalbe enable NX-bit (No eXecute)
|
||||
if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) {
|
||||
x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER)
|
||||
| IA32_MSR_EFER_NX);
|
||||
}
|
||||
if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD))
|
||||
call_all_cpus_sync(&_EnableExecutionDisable, NULL);
|
||||
|
||||
// Ensure that the user half of the address space is clear. This removes
|
||||
// the temporary identity mapping made by the boot loader.
|
||||
@ -384,3 +382,11 @@ X86PagingMethod64Bit::PutPageTableEntryInTable(uint64* entry,
|
||||
SetTableEntry(entry, page);
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
X86PagingMethod64Bit::_EnableExecutionDisable(void* dummy, int cpu)
|
||||
{
|
||||
x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER)
|
||||
| IA32_MSR_EFER_NX);
|
||||
}
|
||||
|
||||
|
@ -149,10 +149,8 @@ struct X86PagingMethodPAE::ToPAESwitcher {
|
||||
call_all_cpus_sync(&_EnablePAE, (void*)(addr_t)physicalPDPT);
|
||||
|
||||
// if availalbe enable NX-bit (No eXecute)
|
||||
if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) {
|
||||
x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER)
|
||||
| IA32_MSR_EFER_NX);
|
||||
}
|
||||
if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD))
|
||||
call_all_cpus_sync(&_EnableExecutionDisable, NULL);
|
||||
|
||||
// set return values
|
||||
_virtualPDPT = pdpt;
|
||||
@ -173,6 +171,12 @@ private:
|
||||
x86_write_cr4(x86_read_cr4() | IA32_CR4_PAE | IA32_CR4_GLOBAL_PAGES);
|
||||
}
|
||||
|
||||
static void _EnableExecutionDisable(void* dummy, int cpu)
|
||||
{
|
||||
x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER)
|
||||
| IA32_MSR_EFER_NX);
|
||||
}
|
||||
|
||||
void _TranslatePageTable(addr_t virtualBase)
|
||||
{
|
||||
page_table_entry* entry = &fPageHole[virtualBase / B_PAGE_SIZE];
|
||||
|
@ -2280,7 +2280,6 @@ device_manager_init(struct kernel_args* args)
|
||||
dm_init_io_resources();
|
||||
|
||||
recursive_lock_init(&sLock, "device manager");
|
||||
init_node_tree();
|
||||
|
||||
register_generic_syscall(DEVICE_MANAGER_SYSCALLS, control_device_manager,
|
||||
1, 0);
|
||||
@ -2300,6 +2299,9 @@ device_manager_init(struct kernel_args* args)
|
||||
"dump an I/O operation");
|
||||
add_debugger_command("io_buffer", &dump_io_buffer, "dump an I/O buffer");
|
||||
add_debugger_command("dma_buffer", &dump_dma_buffer, "dump a DMA buffer");
|
||||
|
||||
init_node_tree();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,6 @@ SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ;
|
||||
KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
|
||||
atomic.S
|
||||
byteorder.S
|
||||
# system_time_asm.S
|
||||
system_time.c
|
||||
|
||||
generic_system_time_nsecs.cpp
|
||||
|
||||
|
@ -164,83 +164,36 @@ FUNCTION(atomic_get):
|
||||
bx lr
|
||||
FUNCTION_END(atomic_get)
|
||||
|
||||
FUNCTION(__sync_fetch_and_add_4):
|
||||
bx lr
|
||||
FUNCTION_END(__sync_fetch_and_add_4)
|
||||
|
||||
/* int64 atomic_add64(vint64 *value, int64 addValue) */
|
||||
//FUNCTION(atomic_add64):
|
||||
// movem.l %d2-%d3/%a2,-(%a7)
|
||||
// move.l (4,%a7),%a2
|
||||
// lea.l (4,%a2),%a1
|
||||
// // addValue
|
||||
// move.l (12,%a7),%d3 /*LSB*/
|
||||
// move.l (8,%a7),%d2 /*MSB*/
|
||||
//miss5: // old value
|
||||
// move.l (%a1),%d1 /*LSB*/
|
||||
// move.l (%a2),%d0 /*MSB*/
|
||||
// add.l %d1,%d3
|
||||
// addx.l %d0,%d2
|
||||
// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1)
|
||||
// bne miss5
|
||||
// // return value d0:d1
|
||||
// movem.l (%a7)+,%d2-%d3/%a2
|
||||
// rts
|
||||
//FUNCTION_END(atomic_add64)
|
||||
FUNCTION(atomic_add64):
|
||||
bx lr
|
||||
FUNCTION_END(atomic_add64)
|
||||
|
||||
/* int64 atomic_and64(vint64 *value, int64 andValue) */
|
||||
//FUNCTION(atomic_and64):
|
||||
//FUNCTION_END(atomic_and64)
|
||||
FUNCTION(atomic_and64):
|
||||
bx lr
|
||||
FUNCTION_END(atomic_and64)
|
||||
|
||||
/* int64 atomic_or64(vint64 *value, int64 orValue) */
|
||||
//FUNCTION(atomic_or64):
|
||||
//FUNCTION_END(atomic_or64)
|
||||
FUNCTION(atomic_or64):
|
||||
bx lr
|
||||
FUNCTION_END(atomic_or64)
|
||||
|
||||
/* int64 atomic_set64(vint64 *value, int64 newValue) */
|
||||
//FUNCTION(atomic_set64):
|
||||
// movem.l %d2-%d3/%a2,-(%a7)
|
||||
// move.l (4,%a7),%a2
|
||||
// lea.l (4,%a2),%a1
|
||||
// // new value
|
||||
// move.l (12,%a7),%d3 /*LSB*/
|
||||
// move.l (8,%a7),%d2 /*MSB*/
|
||||
// // old value
|
||||
// move.l (%a1),%d1 /*LSB*/
|
||||
// move.l (%a2),%d0 /*MSB*/
|
||||
//miss8: cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1)
|
||||
// bne miss8
|
||||
// // return value d0:d1
|
||||
// movem.l (%a7)+,%d2-%d3/%a2
|
||||
// rts
|
||||
//FUNCTION_END(atomic_set64)
|
||||
FUNCTION(atomic_set64):
|
||||
bx lr
|
||||
FUNCTION_END(atomic_set64)
|
||||
|
||||
/* int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) */
|
||||
//FUNCTION(atomic_test_and_set64):
|
||||
// movem.l %d2-%d3/%a2,-(%a7)
|
||||
// move.l (4,%a7),%a2
|
||||
// lea.l (4,%a2),%a1
|
||||
// // new value
|
||||
// move.l (12,%a7),%d3 /*LSB*/
|
||||
// move.l (8,%a7),%d2 /*MSB*/
|
||||
// // test against value
|
||||
// move.l (20,%a7),%d1 /*LSB*/
|
||||
// move.l (16,%a7),%d0 /*MSB*/
|
||||
// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1)
|
||||
// // return value d0:d1
|
||||
// movem.l (%a7)+,%d2-%d3/%a2
|
||||
// rts
|
||||
//FUNCTION_END(atomic_test_and_set64)
|
||||
FUNCTION(atomic_test_and_set64):
|
||||
bx lr
|
||||
FUNCTION_END(atomic_test_and_set64)
|
||||
|
||||
/* int64 atomic_get64(vint64 *value) */
|
||||
//FUNCTION(atomic_get64):
|
||||
// movem.l %d2-%d3/%a2,-(%a7)
|
||||
// move.l (4,%a7),%a2
|
||||
// lea.l (4,%a2),%a1
|
||||
// move.l (%a1),%d1 /*LSB*/
|
||||
// move.l (%a2),%d0 /*MSB*/
|
||||
// move.l %d1,%d3
|
||||
// move.l %d0,%d2
|
||||
// // we must use cas... so we change to the same value if matching,
|
||||
// // else we get the correct one anyway
|
||||
// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1)
|
||||
// // return value
|
||||
// movem.l (%a7)+,%d2-%d3/%a2
|
||||
// rts
|
||||
//FUNCTION_END(atomic_get64)
|
||||
FUNCTION(atomic_get64):
|
||||
bx lr
|
||||
FUNCTION_END(atomic_get64)
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Debug.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)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
STATIC_ASSERT(PTHREAD_STACK_MIN >= MIN_USER_STACK_SIZE
|
||||
&& PTHREAD_STACK_MIN <= MAX_USER_STACK_SIZE);
|
||||
if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
|
12
src/tools/makebootable/platform/u-boot/Jamfile
Normal file
12
src/tools/makebootable/platform/u-boot/Jamfile
Normal file
@ -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++) ;
|
@ -1,4 +1,13 @@
|
||||
SubDir HAIKU_TOP src tools translation bitsinfo ;
|
||||
|
||||
BinCommand bitsinfo : bitsinfo.cpp : be $(TARGET_LIBSUPC++) ;
|
||||
BinCommand bitsinfo :
|
||||
bitsinfo.cpp
|
||||
: be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ;
|
||||
|
||||
AddResources bitsinfo : bitsinfo.rdef ;
|
||||
|
||||
DoCatalogs bitsinfo :
|
||||
x-vnd.Haiku-bitsinfo
|
||||
:
|
||||
bitsinfo.cpp
|
||||
;
|
||||
|
@ -38,10 +38,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ByteOrder.h>
|
||||
#include <Catalog.h>
|
||||
#include <File.h>
|
||||
#include <TranslatorFormats.h>
|
||||
#include <StorageDefs.h>
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "bitsinfo"
|
||||
|
||||
struct ColorSpaceName {
|
||||
color_space id;
|
||||
const char *name;
|
||||
@ -62,7 +66,8 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
|
||||
// read in the rest of the header
|
||||
ssize_t size = sizeof(TranslatorBitmap);
|
||||
if (file.Read(reinterpret_cast<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;
|
||||
}
|
||||
if (!bdumppixels)
|
||||
@ -72,28 +77,29 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
|
||||
// convert to host byte order
|
||||
if (swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap),
|
||||
B_SWAP_BENDIAN_TO_HOST) != B_OK) {
|
||||
printf("\nError: Unable to swap byte order\n");
|
||||
printf(B_TRANSLATE("\nError: Unable to swap byte order\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\nBe bitmap (\"bits\") header for: %s\n\n", filepath);
|
||||
printf(B_TRANSLATE("\nBe bitmap (\"bits\") header for: %s\n\n"),
|
||||
filepath);
|
||||
|
||||
const uint32 kbitsmagic = 0x62697473UL;
|
||||
// in ASCII, this number looks like "bits"
|
||||
printf("magic number: 0x%.8lx ", header.magic);
|
||||
if (header.magic == kbitsmagic)
|
||||
printf("(valid)\n");
|
||||
printf(B_TRANSLATE("magic number: 0x%.8lx (valid)\n"),
|
||||
header.magic);
|
||||
else
|
||||
printf("(INVALID, should be: 0x%.8lx)\n",
|
||||
kbitsmagic);
|
||||
printf("bounds: (%f, %f, %f, %f)\n",
|
||||
printf(B_TRANSLATE("magic number: 0x%.8lx (INVALID, should be: "
|
||||
"0x%.8lx)\n"), header.magic, kbitsmagic);
|
||||
printf(B_TRANSLATE("bounds: (%f, %f, %f, %f)\n"),
|
||||
header.bounds.left, header.bounds.top,
|
||||
header.bounds.right, header.bounds.bottom);
|
||||
printf("dimensions: %d x %d\n",
|
||||
printf(B_TRANSLATE("dimensions: %d x %d\n"),
|
||||
static_cast<int>(header.bounds.Width() + 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));
|
||||
|
||||
// print out colorspace if it matches an item in the list
|
||||
@ -149,15 +155,15 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
|
||||
int32 i;
|
||||
for (i = 0; i < kncolorspaces; i++) {
|
||||
if (header.colors == colorspaces[i].id) {
|
||||
printf("color space: %s\n", colorspaces[i].name);
|
||||
printf(B_TRANSLATE("color space: %s\n"), colorspaces[i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == kncolorspaces)
|
||||
printf("color space: Unknown (0x%.8lx)\n",
|
||||
printf(B_TRANSLATE("color space: Unknown (0x%.8lx)\n"),
|
||||
static_cast<unsigned long>(header.colors));
|
||||
|
||||
printf("data size: %u\n",
|
||||
printf(B_TRANSLATE("data size: %u\n"),
|
||||
static_cast<unsigned int>(header.dataSize));
|
||||
|
||||
if (bdumppixels) {
|
||||
@ -178,18 +184,19 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Sorry, %s isn't supported yet"
|
||||
" for this color space\n", kpixels);
|
||||
printf(B_TRANSLATE("Sorry, %s isn't supported yet"
|
||||
" for this color space\n"), kpixels);
|
||||
return;
|
||||
}
|
||||
uint8 *prow = new uint8[header.rowBytes];
|
||||
if (!prow) {
|
||||
printf("Error: Not enough memory for row buffer\n");
|
||||
printf(B_TRANSLATE("Error: Not enough memory for row "
|
||||
"buffer\n"));
|
||||
return;
|
||||
}
|
||||
ssize_t ret, n;
|
||||
uint32 totalbytes = 0;
|
||||
printf("pixel data (%s):\n", components);
|
||||
printf(B_TRANSLATE("pixel data (%s):\n"), components);
|
||||
while ((ret = file.Read(prow, header.rowBytes)) > 0) {
|
||||
n = 0;
|
||||
while (n < ret) {
|
||||
@ -205,18 +212,21 @@ PrintBitsInfo(const char *filepath, bool bdumppixels)
|
||||
}
|
||||
|
||||
} else
|
||||
printf("Error opening %s\n", filepath);
|
||||
printf(B_TRANSLATE_COMMENT("Error opening %s\n",
|
||||
"file path is opening"), filepath);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1) {
|
||||
printf("\nbitsinfo - reports information about a Be bitmap (\"bits\") image\n");
|
||||
printf("\nUsage:\n");
|
||||
printf("bitsinfo [options] filename.bits\n\n");
|
||||
printf("Options:\n\n");
|
||||
printf("\t%s \t print RGB color for each pixel\n", kpixels);
|
||||
printf(B_TRANSLATE("\nbitsinfo - reports information about a Be "
|
||||
"bitmap (\"bits\") image\n"));
|
||||
printf(B_TRANSLATE("\nUsage:\n"));
|
||||
printf(B_TRANSLATE("bitsinfo [options] filename.bits\n\n"));
|
||||
printf(B_TRANSLATE("Options:\n\n"));
|
||||
printf(B_TRANSLATE("\t%s \t print RGB color for each pixel\n"),
|
||||
kpixels);
|
||||
}
|
||||
else {
|
||||
int32 first = 1;
|
||||
|
17
src/tools/translation/bitsinfo/bitsinfo.rdef
Normal file
17
src/tools/translation/bitsinfo/bitsinfo.rdef
Normal file
@ -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;
|
@ -1,4 +1,11 @@
|
||||
SubDir HAIKU_TOP src tools translation bmpinfo ;
|
||||
|
||||
BinCommand bmpinfo : bmpinfo.cpp : be ;
|
||||
BinCommand bmpinfo : bmpinfo.cpp : be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ;
|
||||
|
||||
AddResources bmpinfo : bmpinfo.rdef ;
|
||||
|
||||
DoCatalogs bmpinfo :
|
||||
x-vnd.Haiku-bmpsinfo
|
||||
:
|
||||
bmpinfo.cpp
|
||||
;
|
||||
|
@ -36,10 +36,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ByteOrder.h>
|
||||
#include <Catalog.h>
|
||||
#include <File.h>
|
||||
#include <TranslatorFormats.h>
|
||||
#include <StorageDefs.h>
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "bmpinfo"
|
||||
|
||||
#define BMP_NO_COMPRESS 0
|
||||
#define BMP_RLE8_COMPRESS 1
|
||||
#define BMP_RLE4_COMPRESS 2
|
||||
@ -82,7 +86,7 @@ print_bmp_info(BFile &file)
|
||||
|
||||
ssize_t size = 14;
|
||||
if (file.Read(buf, size) != size) {
|
||||
printf("Error: unable to read BMP file header\n");
|
||||
printf(B_TRANSLATE("Error: unable to read BMP file header\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -96,16 +100,18 @@ print_bmp_info(BFile &file)
|
||||
swap_data(B_UINT32_TYPE, (reinterpret_cast<uint8 *> (&fh)) + 2,
|
||||
12, B_SWAP_LENDIAN_TO_HOST);
|
||||
|
||||
printf("\nFile Header:\n");
|
||||
printf(" magic: 0x%.4x (should be: 0x424d)\n", fh.magic);
|
||||
printf(" file size: 0x%.8lx (%lu)\n", fh.fileSize, fh.fileSize);
|
||||
printf(" reserved: 0x%.8lx (should be: 0x%.8x)\n", fh.reserved, 0);
|
||||
printf("data offset: 0x%.8lx (%lu) (should be: >= 54 for MS format "
|
||||
"and >= 26 for OS/2 format)\n", fh.dataOffset, fh.dataOffset);
|
||||
printf(B_TRANSLATE("\nFile Header:\n"));
|
||||
printf(B_TRANSLATE(" magic: 0x%.4x (should be: 0x424d)\n"), fh.magic);
|
||||
printf(B_TRANSLATE(" file size: 0x%.8lx (%lu)\n"), fh.fileSize,
|
||||
fh.fileSize);
|
||||
printf(B_TRANSLATE(" reserved: 0x%.8lx (should be: 0x%.8x)\n"),
|
||||
fh.reserved, 0);
|
||||
printf(B_TRANSLATE("data offset: 0x%.8lx (%lu) (should be: >= 54 for MS "
|
||||
"format and >= 26 for OS/2 format)\n"), fh.dataOffset, fh.dataOffset);
|
||||
|
||||
uint32 headersize = 0;
|
||||
if (file.Read(&headersize, 4) != 4) {
|
||||
printf("Error: unable to read info header size\n");
|
||||
printf(B_TRANSLATE("Error: unable to read info header size\n"));
|
||||
return;
|
||||
}
|
||||
swap_data(B_UINT32_TYPE, &headersize, 4, B_SWAP_LENDIAN_TO_HOST);
|
||||
@ -115,7 +121,7 @@ print_bmp_info(BFile &file)
|
||||
MSInfoHeader msh;
|
||||
msh.size = headersize;
|
||||
if (file.Read(reinterpret_cast<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;
|
||||
}
|
||||
|
||||
@ -123,22 +129,33 @@ print_bmp_info(BFile &file)
|
||||
swap_data(B_UINT32_TYPE, reinterpret_cast<uint8 *> (&msh) + 4, 36,
|
||||
B_SWAP_LENDIAN_TO_HOST);
|
||||
|
||||
printf("\nMS Info Header:\n");
|
||||
printf(" header size: 0x%.8lx (%lu) (should be: 40)\n", msh.size, msh.size);
|
||||
printf(" width: %lu\n", msh.width);
|
||||
printf(" height: %lu\n", msh.height);
|
||||
printf(" planes: %u (should be: 1)\n", msh.planes);
|
||||
printf(" bits per pixel: %u (should be: 1,4,8,16,24 or 32)\n", msh.bitsperpixel);
|
||||
printf(" compression: %s (%lu)\n",
|
||||
((msh.compression == BMP_NO_COMPRESS) ? ("none") :
|
||||
((msh.compression == BMP_RLE8_COMPRESS) ? ("RLE 8") :
|
||||
((msh.compression == BMP_RLE4_COMPRESS) ? ("RLE 4") :
|
||||
("unknown")))), msh.compression);
|
||||
printf(" image size: 0x%.8lx (%lu)\n", msh.imagesize, msh.imagesize);
|
||||
printf(" x pixels/meter: %lu\n", msh.xpixperm);
|
||||
printf(" y pixels/meter: %lu\n", msh.ypixperm);
|
||||
printf(" colors used: %lu\n", msh.colorsused);
|
||||
printf("colors important: %lu\n", msh.colorsimportant);
|
||||
printf(B_TRANSLATE("\nMS Info Header:\n"));
|
||||
printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: "
|
||||
"40)\n"), msh.size, msh.size);
|
||||
printf(B_TRANSLATE(" width: %lu\n"), msh.width);
|
||||
printf(B_TRANSLATE(" height: %lu\n"), msh.height);
|
||||
printf(B_TRANSLATE(" planes: %u (should be: 1)\n"),
|
||||
msh.planes);
|
||||
printf(B_TRANSLATE(" bits per pixel: %u (should be: 1,4,8,16,24 or "
|
||||
"32)\n"), msh.bitsperpixel);
|
||||
if (msh.compression == BMP_NO_COMPRESS)
|
||||
printf(B_TRANSLATE(" compression: none (%lu)\n"),
|
||||
msh.compression);
|
||||
else if (msh.compression == BMP_RLE8_COMPRESS)
|
||||
printf(B_TRANSLATE(" compression: RLE8 (%lu)\n"),
|
||||
msh.compression);
|
||||
else if (msh.compression == BMP_RLE4_COMPRESS)
|
||||
printf(B_TRANSLATE(" compression: RLE4 (%lu)\n"),
|
||||
msh.compression);
|
||||
else
|
||||
printf(B_TRANSLATE(" compression: unknown (%lu)\n"),
|
||||
msh.compression);
|
||||
printf(B_TRANSLATE(" image size: 0x%.8lx (%lu)\n"), msh.imagesize,
|
||||
msh.imagesize);
|
||||
printf(B_TRANSLATE(" x pixels/meter: %lu\n"), msh.xpixperm);
|
||||
printf(B_TRANSLATE(" y pixels/meter: %lu\n"), msh.ypixperm);
|
||||
printf(B_TRANSLATE(" colors used: %lu\n"), msh.colorsused);
|
||||
printf(B_TRANSLATE("colors important: %lu\n"), msh.colorsimportant);
|
||||
|
||||
} else if (headersize == sizeof(OS2InfoHeader)) {
|
||||
// OS/2 format
|
||||
@ -146,7 +163,8 @@ print_bmp_info(BFile &file)
|
||||
OS2InfoHeader os2;
|
||||
os2.size = headersize;
|
||||
if (file.Read(reinterpret_cast<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;
|
||||
}
|
||||
|
||||
@ -154,17 +172,18 @@ print_bmp_info(BFile &file)
|
||||
swap_data(B_UINT32_TYPE, reinterpret_cast<uint8 *> (&os2) + 4, 8,
|
||||
B_SWAP_LENDIAN_TO_HOST);
|
||||
|
||||
printf("\nOS/2 Info Header:\n");
|
||||
printf(" header size: 0x%.8lx (%lu) (should be: 12)\n", os2.size, os2.size);
|
||||
printf(" width: %u\n", os2.width);
|
||||
printf(" height: %u\n", os2.height);
|
||||
printf(" planes: %u (should be: 1)\n", os2.planes);
|
||||
printf("bits per pixel: %u (should be: 1,4,8 or 24)\n",
|
||||
printf(B_TRANSLATE("\nOS/2 Info Header:\n"));
|
||||
printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: 12)\n"),
|
||||
os2.size, os2.size);
|
||||
printf(B_TRANSLATE(" width: %u\n"), os2.width);
|
||||
printf(B_TRANSLATE(" height: %u\n"), os2.height);
|
||||
printf(B_TRANSLATE(" planes: %u (should be: 1)\n"), os2.planes);
|
||||
printf(B_TRANSLATE("bits per pixel: %u (should be: 1,4,8 or 24)\n"),
|
||||
os2.bitsperpixel);
|
||||
|
||||
} else
|
||||
printf("Error: info header size (%lu) does not match MS or OS/2 "
|
||||
"info header size\n", headersize);
|
||||
printf(B_TRANSLATE("Error: info header size (%lu) does not match MS "
|
||||
"or OS/2 info header size\n"), headersize);
|
||||
}
|
||||
|
||||
int
|
||||
@ -173,18 +192,20 @@ main(int argc, char **argv)
|
||||
printf("\n");
|
||||
|
||||
if (argc == 1) {
|
||||
printf("bmpinfo - reports information about a BMP image file\n");
|
||||
printf("\nUsage:\n");
|
||||
printf("bmpinfo filename.bmp\n");
|
||||
printf(B_TRANSLATE("bmpinfo - reports information about a BMP image "
|
||||
"file\n"));
|
||||
printf(B_TRANSLATE("\nUsage:\n"));
|
||||
printf(B_TRANSLATE("bmpinfo filename.bmp\n"));
|
||||
}
|
||||
else {
|
||||
BFile file;
|
||||
|
||||
for (int32 i = 1; i < argc; i++) {
|
||||
if (file.SetTo(argv[i], B_READ_ONLY) != B_OK)
|
||||
printf("\nError opening %s\n", argv[i]);
|
||||
printf(B_TRANSLATE("\nError opening %s\n"), argv[i]);
|
||||
else {
|
||||
printf("\nBMP image information for: %s\n", argv[i]);
|
||||
printf(B_TRANSLATE("\nBMP image information for: %s\n"),
|
||||
argv[i]);
|
||||
print_bmp_info(file);
|
||||
}
|
||||
}
|
||||
|
17
src/tools/translation/bmpinfo/bmpinfo.rdef
Normal file
17
src/tools/translation/bmpinfo/bmpinfo.rdef
Normal 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;
|
@ -1,4 +1,13 @@
|
||||
SubDir HAIKU_TOP src tools translation tgainfo ;
|
||||
|
||||
BinCommand tgainfo : tgainfo.cpp : be ;
|
||||
BinCommand tgainfo :
|
||||
tgainfo.cpp
|
||||
: be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ;
|
||||
|
||||
AddResources tgainfo : tgainfo.rdef ;
|
||||
|
||||
DoCatalogs tgainfo :
|
||||
x-vnd.Haiku-tgainfo
|
||||
:
|
||||
tgainfo.cpp
|
||||
;
|
||||
|
@ -36,10 +36,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ByteOrder.h>
|
||||
#include <Catalog.h>
|
||||
#include <File.h>
|
||||
#include <TranslatorFormats.h>
|
||||
#include <StorageDefs.h>
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "tgainfo"
|
||||
|
||||
#define max(x,y) ((x > y) ? x : y)
|
||||
#define DATA_BUFFER_SIZE 64
|
||||
|
||||
@ -99,8 +103,8 @@ const char *
|
||||
colormaptype(uint8 n)
|
||||
{
|
||||
switch (n) {
|
||||
case 0: return "No colormap";
|
||||
case 1: return "colormap";
|
||||
case 0: return B_TRANSLATE("No colormap");
|
||||
case 1: return B_TRANSLATE("colormap");
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
@ -109,15 +113,16 @@ const char *
|
||||
imagetype(uint8 n)
|
||||
{
|
||||
switch (n) {
|
||||
case 0: return "No Image Data";
|
||||
case 1: return "colormap";
|
||||
case 2: return "true color";
|
||||
case 3: return "grayscale";
|
||||
case 9: return "RLE colormap";
|
||||
case 10: return "RLE true color";
|
||||
case 11: return "RLE grayscale";
|
||||
case 0: return B_TRANSLATE("No Image Data");
|
||||
case 1: return B_TRANSLATE("colormap");
|
||||
case 2: return B_TRANSLATE("true color");
|
||||
case 3: return B_TRANSLATE("grayscale");
|
||||
case 9: return B_TRANSLATE("RLE colormap");
|
||||
case 10: return B_TRANSLATE("RLE true color");
|
||||
case 11: return B_TRANSLATE("RLE grayscale");
|
||||
default: break;
|
||||
}
|
||||
return "unknown";
|
||||
return B_TRANSLATE("unknown");
|
||||
}
|
||||
|
||||
uint16
|
||||
@ -140,7 +145,7 @@ print_tga_info(BFile &file)
|
||||
// read in TGA headers
|
||||
ssize_t size = TGA_HEADERS_SIZE;
|
||||
if (size > 0 && file.Read(buf, size) != size) {
|
||||
printf("Error: unable to read all TGA headers\n");
|
||||
printf(B_TRANSLATE("Error: unable to read all TGA headers\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -150,12 +155,15 @@ print_tga_info(BFile &file)
|
||||
fh.colormaptype = buf[1];
|
||||
fh.imagetype = buf[2];
|
||||
|
||||
printf("\nFile Header:\n");
|
||||
printf(" id length: %d\n", fh.idlength);
|
||||
printf(B_TRANSLATE("\nFile Header:\n"));
|
||||
printf(B_TRANSLATE(" id length: %d\n"), static_cast<int>(fh.idlength));
|
||||
|
||||
printf("colormap type: %d (%s)\n", fh.colormaptype,
|
||||
colormaptype(fh.colormaptype));
|
||||
printf(" image type: %d (%s)\n", fh.imagetype, imagetype(fh.imagetype));
|
||||
printf(B_TRANSLATE("colormap type: %d (%s)\n"),
|
||||
static_cast<int>(fh.colormaptype),
|
||||
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
|
||||
@ -164,10 +172,13 @@ print_tga_info(BFile &file)
|
||||
mapspec.length = tga_uint16(reinterpret_cast<char *>(buf), 5);
|
||||
mapspec.entrysize = buf[7];
|
||||
|
||||
printf("\nColormap Spec:\n");
|
||||
printf("first entry: %d\n", mapspec.firstentry);
|
||||
printf(" length: %d\n", mapspec.length);
|
||||
printf(" entry size: %d\n", mapspec.entrysize);
|
||||
printf(B_TRANSLATE("\nColormap Spec:\n"));
|
||||
printf(B_TRANSLATE("first entry: %d\n"),
|
||||
static_cast<int>(mapspec.firstentry));
|
||||
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
|
||||
@ -179,20 +190,47 @@ print_tga_info(BFile &file)
|
||||
imagespec.depth = buf[16];
|
||||
imagespec.descriptor = buf[17];
|
||||
|
||||
printf("\nImage Spec:\n");
|
||||
printf(" x origin: %d\n", imagespec.xorigin);
|
||||
printf(" y origin: %d\n", imagespec.yorigin);
|
||||
printf(" width: %d\n", imagespec.width);
|
||||
printf(" height: %d\n", imagespec.height);
|
||||
printf(" depth: %d\n", imagespec.depth);
|
||||
printf("descriptor: 0x%.2x\n", imagespec.descriptor);
|
||||
printf("\talpha (attr): %d\n",
|
||||
imagespec.descriptor & TGA_DESC_ALPHABITS);
|
||||
printf("\t origin: %d (%s %s)\n",
|
||||
imagespec.descriptor & (TGA_ORIGIN_VERT_BIT | TGA_ORIGIN_HORZ_BIT),
|
||||
((imagespec.descriptor & TGA_ORIGIN_VERT_BIT) ? "top" : "bottom"),
|
||||
((imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) ? "right" : "left"));
|
||||
printf("\t bits 7 & 6: %d\n", imagespec.descriptor & TGA_DESC_BITS76);
|
||||
printf(B_TRANSLATE("\nImage Spec:\n"));
|
||||
printf(B_TRANSLATE(" x origin: %d\n"),
|
||||
static_cast<int>(imagespec.xorigin));
|
||||
printf(B_TRANSLATE(" y origin: %d\n"),
|
||||
static_cast<int>(imagespec.yorigin));
|
||||
printf(B_TRANSLATE(" width: %d\n"),
|
||||
static_cast<int>(imagespec.width));
|
||||
printf(B_TRANSLATE(" height: %d\n"),
|
||||
static_cast<int>(imagespec.height));
|
||||
printf(B_TRANSLATE(" depth: %d\n"),
|
||||
static_cast<int>(imagespec.depth));
|
||||
printf(B_TRANSLATE("descriptor: 0x%.2x\n"),
|
||||
static_cast<int>(imagespec.descriptor));
|
||||
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
|
||||
@ -208,107 +246,128 @@ print_tga_info(BFile &file)
|
||||
extoffset = tga_uint32(tgafooter, 0);
|
||||
devoffset = tga_uint32(tgafooter, 4);
|
||||
|
||||
printf("\nTGA Footer:\n");
|
||||
printf("extension offset: 0x%.8lx (%ld)\n", extoffset, extoffset);
|
||||
printf("developer offset: 0x%.8lx (%ld)\n", devoffset, devoffset);
|
||||
printf("signature: %s\n", tgafooter + 8);
|
||||
printf(B_TRANSLATE("\nTGA Footer:\n"));
|
||||
printf(B_TRANSLATE("extension offset: 0x%.8lx (%ld)\n"),
|
||||
static_cast<long int>(extoffset),
|
||||
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) {
|
||||
char extbuf[TGA_EXT_LEN];
|
||||
if (file.ReadAt(extoffset, extbuf, TGA_EXT_LEN) == TGA_EXT_LEN) {
|
||||
|
||||
printf("\nExtension Area:\n");
|
||||
printf(B_TRANSLATE("\nExtension Area:\n"));
|
||||
|
||||
char strbuffer[LINE_LEN];
|
||||
|
||||
uint16 extsize = tga_uint16(extbuf, 0);
|
||||
if (extsize < TGA_EXT_LEN) {
|
||||
printf("\nError: extension area is too small (%d)\n", extsize);
|
||||
printf(B_TRANSLATE("\nError: extension "
|
||||
"area is too small (%d)\n"), extsize);
|
||||
return;
|
||||
}
|
||||
printf("size: %d\n", extsize);
|
||||
printf(B_TRANSLATE("size: %d\n"), extsize);
|
||||
|
||||
memset(strbuffer, 0, LINE_LEN);
|
||||
strncpy(strbuffer, extbuf + 2, 41);
|
||||
printf("author: \"%s\"\n", strbuffer);
|
||||
|
||||
printf("comments:\n");
|
||||
printf(B_TRANSLATE("comments:\n"));
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
memset(strbuffer, 0, LINE_LEN);
|
||||
strcpy(strbuffer, extbuf + 43 + (i * 81));
|
||||
printf("\tline %ld: \"%s\"\n", i + 1, strbuffer);
|
||||
printf(B_TRANSLATE("\tline %ld: \"%s\"\n"),
|
||||
static_cast<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, 371), tga_uint16(extbuf, 373),
|
||||
tga_uint16(extbuf, 375), tga_uint16(extbuf, 377));
|
||||
|
||||
memset(strbuffer, 0, LINE_LEN);
|
||||
strncpy(strbuffer, extbuf + 379, 41);
|
||||
printf("job name: \"%s\"\n", strbuffer);
|
||||
printf(B_TRANSLATE("job name: \"%s\"\n"), strbuffer);
|
||||
|
||||
printf("job time (hh:mm:ss): %.2d:%.2d:%.2d\n",
|
||||
tga_uint16(extbuf, 420), tga_uint16(extbuf, 422),
|
||||
tga_uint16(extbuf, 424));
|
||||
printf(B_TRANSLATE("job time (hh:mm:ss): "
|
||||
"%.2d:%.2d:%.2d\n"), tga_uint16(extbuf, 420),
|
||||
tga_uint16(extbuf, 422), tga_uint16(extbuf, 424));
|
||||
|
||||
memset(strbuffer, 0, LINE_LEN);
|
||||
strncpy(strbuffer, extbuf + 426, 41);
|
||||
printf("software id: \"%s\"\n", strbuffer);
|
||||
printf(B_TRANSLATE("software id: \"%s\"\n"),
|
||||
strbuffer);
|
||||
|
||||
char strver[] = "[null]";
|
||||
if (extbuf[469] != '\0') {
|
||||
strver[0] = extbuf[469];
|
||||
strver[1] = '\0';
|
||||
}
|
||||
printf("software version, letter: %d, %s\n",
|
||||
tga_uint16(extbuf, 467), strver);
|
||||
printf(B_TRANSLATE("software version, letter: %d, "
|
||||
"%s\n"), tga_uint16(extbuf, 467), strver);
|
||||
|
||||
printf("key color (A,R,G,B): %d, %d, %d, %d\n",
|
||||
extbuf[470], extbuf[471], extbuf[472], extbuf[473]);
|
||||
printf(B_TRANSLATE("key color (A,R,G,B): %d, %d, %d, "
|
||||
"%d\n"), extbuf[470], extbuf[471], extbuf[472],
|
||||
extbuf[473]);
|
||||
|
||||
printf("pixel aspect ratio: %d / %d\n",
|
||||
printf(B_TRANSLATE("pixel aspect ratio: %d / %d\n"),
|
||||
tga_uint16(extbuf, 474), tga_uint16(extbuf, 476));
|
||||
|
||||
printf("gamma value: %d / %d\n",
|
||||
printf(B_TRANSLATE("gamma value: %d / %d\n"),
|
||||
tga_uint16(extbuf, 478), tga_uint16(extbuf, 480));
|
||||
|
||||
printf("color correction offset: 0x%.8lx (%ld)\n",
|
||||
tga_uint32(extbuf, 482), tga_uint32(extbuf, 482));
|
||||
printf("postage stamp offset: 0x%.8lx (%ld)\n",
|
||||
tga_uint32(extbuf, 486), tga_uint32(extbuf, 486));
|
||||
printf("scan line offset: 0x%.8lx (%ld)\n",
|
||||
tga_uint32(extbuf, 490), tga_uint32(extbuf, 490));
|
||||
printf(B_TRANSLATE("color correction offset: 0x%.8lx "
|
||||
"(%ld)\n"), tga_uint32(extbuf, 482),
|
||||
tga_uint32(extbuf, 482));
|
||||
printf(B_TRANSLATE("postage stamp offset: 0x%.8lx "
|
||||
"(%ld)\n"), tga_uint32(extbuf, 486),
|
||||
tga_uint32(extbuf, 486));
|
||||
printf(B_TRANSLATE("scan line offset: 0x%.8lx "
|
||||
"(%ld)\n"), tga_uint32(extbuf, 490),
|
||||
tga_uint32(extbuf, 490));
|
||||
|
||||
const char *strattrtype = NULL;
|
||||
uint8 attrtype = extbuf[494];
|
||||
switch (attrtype) {
|
||||
case 0: strattrtype = "no alpha"; break;
|
||||
case 1: strattrtype = "undefined, ignore"; break;
|
||||
case 2: strattrtype = "undefined, retain"; break;
|
||||
case 3: strattrtype = "alpha"; break;
|
||||
case 4: strattrtype = "pre-multiplied alpha"; break;
|
||||
case 0: strattrtype
|
||||
= B_TRANSLATE("no alpha"); break;
|
||||
case 1: strattrtype
|
||||
= B_TRANSLATE("undefined, ignore"); break;
|
||||
case 2: strattrtype
|
||||
= B_TRANSLATE("undefined, retain"); break;
|
||||
case 3: strattrtype
|
||||
= B_TRANSLATE("alpha"); break;
|
||||
case 4: strattrtype
|
||||
= B_TRANSLATE("pre-multiplied alpha"); break;
|
||||
default:
|
||||
if (attrtype > 4 && attrtype < 128)
|
||||
strattrtype = "reserved";
|
||||
strattrtype = B_TRANSLATE("reserved");
|
||||
else
|
||||
strattrtype = "unassigned";
|
||||
strattrtype = B_TRANSLATE("unassigned");
|
||||
break;
|
||||
}
|
||||
printf("attributes type: %d (%s)\n", attrtype, strattrtype);
|
||||
printf(B_TRANSLATE("attributes type: %d (%s)\n"),
|
||||
attrtype, strattrtype);
|
||||
|
||||
} else
|
||||
printf("\nError: Unable to read entire extension area\n");
|
||||
printf(B_TRANSLATE("\nError: Unable to read entire "
|
||||
"extension area\n"));
|
||||
}
|
||||
|
||||
} else
|
||||
printf("\nTGA footer not found\n");
|
||||
printf(B_TRANSLATE("\nTGA footer not found\n"));
|
||||
|
||||
} else
|
||||
printf("\nError: Unable to read TGA footer section\n");
|
||||
printf(B_TRANSLATE("\nError: Unable to read TGA footer "
|
||||
"section\n"));
|
||||
|
||||
} else
|
||||
printf("\nError: Unable to get file size\n");
|
||||
printf(B_TRANSLATE("\nError: Unable to get file size\n"));
|
||||
}
|
||||
|
||||
int
|
||||
@ -317,18 +376,18 @@ main(int argc, char **argv)
|
||||
printf("\n");
|
||||
|
||||
if (argc == 1) {
|
||||
printf("tgainfo - reports information about a TGA image file\n");
|
||||
printf("\nUsage:\n");
|
||||
printf("tgainfo filename.tga\n");
|
||||
printf(B_TRANSLATE("tgainfo - reports information about a TGA image file\n"));
|
||||
printf(B_TRANSLATE("\nUsage:\n"));
|
||||
printf(B_TRANSLATE("tgainfo filename.tga\n"));
|
||||
}
|
||||
else {
|
||||
BFile file;
|
||||
|
||||
for (int32 i = 1; i < argc; i++) {
|
||||
if (file.SetTo(argv[i], B_READ_ONLY) != B_OK)
|
||||
printf("\nError opening %s\n", argv[i]);
|
||||
printf(B_TRANSLATE("\nError opening %s\n"), argv[i]);
|
||||
else {
|
||||
printf("\nTGA image information for: %s\n", argv[i]);
|
||||
printf(B_TRANSLATE("\nTGA image information for: %s\n"), argv[i]);
|
||||
print_tga_info(file);
|
||||
}
|
||||
}
|
||||
|
17
src/tools/translation/tgainfo/tgainfo.rdef
Normal file
17
src/tools/translation/tgainfo/tgainfo.rdef
Normal 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;
|
Loading…
x
Reference in New Issue
Block a user