Merge branch 'master' into sam460ex

This commit is contained in:
François Revol 2013-09-17 13:22:26 +02:00
commit 228524afb6
100 changed files with 2874 additions and 596 deletions

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -1,4 +1,4 @@
1 french x-vnd.haiku-icon_o_matic 605140404
1 french x-vnd.haiku-icon_o_matic 806315965
Select All Icon-O-Matic-PathManipulator Sélectionner tout
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

View File

@ -1,7 +1,8 @@
1 finnish x-vnd.Haiku-libmail 161731481
1 finnish x-vnd.Haiku-libmail 4037525365
Partially download messages larger than ProtocolConfigView Osittain ladatut viestit suurempia kuin
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:

View File

@ -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 Ніякія опцыі недаступныя

View File

@ -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

View File

@ -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ä

View File

@ -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

View File

@ -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

View File

@ -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 設定がありません

View File

@ -1,3 +1,8 @@
* Determine how to handle atomic functions on ARM.
GCC inlines are not supported, since the instructionset is ill-equiped for
this on older (pre-ARMv7) architectures. We possibly have to do something
similar to the linux kernel helper functions for this....
* Figure out how to get page flags (modified/accessed) and implement it ;)
use unmapped/read-only mappings to trigger soft faults
for tracking used/modified flags for ARMv5 and ARMv6

View File

@ -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)

View File

@ -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 */

View File

@ -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); }

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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 ;

View 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
;

View 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
};

View 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 */

View File

@ -633,8 +633,9 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
inode->SetAccessTime(&timespec);
inode->SetCreationTime(&timespec);
inode->SetModificationTime(&timespec);
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);
}
}

View File

@ -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 \

View File

@ -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;
}

View File

@ -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);

View File

@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui.o
:
AbstractGeneralPage.cpp

View File

@ -4,9 +4,6 @@ UsePrivateHeaders shared ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui_chart.o
:
BigtimeChartAxisLegendSource.cpp

View File

@ -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

View File

@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui_table.o
:
AbstractTable.cpp

View File

@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_gui_thread_window.o
:
ActivityPage.cpp

View File

@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_model.o
:
Model.cpp

View File

@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_model_loader.o
:
AbstractModelLoader.cpp

View File

@ -5,9 +5,6 @@ UsePrivateSystemHeaders ;
UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
MergeObject DebugAnalyzer_util.o
:
DataSource.cpp

View File

@ -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

View File

@ -1,8 +1,5 @@
SubDir HAIKU_TOP src apps debugger arch x86 disasm ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
UsePrivateHeaders shared ;
UseHeaders [ LibraryHeaders udis86 ] ;

View File

@ -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;

View File

@ -1,8 +1,5 @@
SubDir HAIKU_TOP src apps debugger arch x86_64 disasm ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
UsePrivateHeaders shared ;
UseHeaders [ LibraryHeaders udis86 ] ;

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 ] ;

View File

@ -1,8 +1,5 @@
SubDir HAIKU_TOP src apps debugger dwarf ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
UsePrivateHeaders kernel shared ;
UsePrivateSystemHeaders ;

View File

@ -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);
}
}

View File

@ -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;
};

View 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;
}

View 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

View File

@ -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()
{

View File

@ -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;
};

View File

@ -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

View File

@ -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;
};

View File

@ -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()
{

View File

@ -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:

View File

@ -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;

View File

@ -38,6 +38,7 @@ Application HaikuDepot :
MainWindow.cpp
Model.cpp
PackageInfo.cpp
PackageInfoListener.cpp
PackageInfoView.cpp
PackageListView.cpp
PackageManager.cpp

View File

@ -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);

View File

@ -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();

View File

@ -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)
);
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View 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()
{
}

View 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

View File

@ -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));
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,3 @@
SubDir HAIKU_TOP src bin makebootable platform u-boot ;
BinCommand makebootable : makebootable.cpp ;

View File

@ -0,0 +1,6 @@
int
main()
{
return 0;
}

View File

@ -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;
}

View File

@ -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\")";

View File

@ -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)
{

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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) =

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -753,15 +753,6 @@ arch_cpu_init_percpu(kernel_args* args, int cpu)
}
}
// If availalbe enable NX-bit (No eXecute). Boot CPU can not enable
// NX-bit here since PAE should be enabled first.
if (cpu != 0) {
if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) {
x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER)
| IA32_MSR_EFER_NX);
}
}
return B_OK;
}

View File

@ -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);
}

View File

@ -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];

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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;

View 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++) ;

View File

@ -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
;

View File

@ -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;

View 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;

View File

@ -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
;

View File

@ -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);
}
}

View 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;

View File

@ -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
;

View File

@ -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);
}
}

View 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;