diff --git a/build/jam/FloppyBootImage b/build/jam/FloppyBootImage index ea05ca505b..3c792844a7 100644 --- a/build/jam/FloppyBootImage +++ b/build/jam/FloppyBootImage @@ -3,12 +3,15 @@ local X86_ONLY = ; local PPC_ONLY = ; +local ARM_ONLY = ; if $(TARGET_ARCH) = x86 { X86_ONLY = "" ; } else if $(TARGET_ARCH) = ppc { X86_ONLY = ; } else if $(TARGET_ARCH) = m68k { X86_ONLY = ; +} else if $(TARGET_ARCH) = arm { + ARM_ONLY = "" ; } local GPL_ONLY = ; @@ -80,6 +83,7 @@ if $(TARGET_ARCH) = x86 { # drivers AddNewDriversToFloppyBootArchive disk scsi : scsi_cd scsi_disk ; +AddNewDriversToFloppyBootArchive disk : $(ARM_ONLY)norflash ; if $(USB_BOOT) = 1 { AddDriversToFloppyBootArchive disk usb : usb_disk ; } @@ -122,7 +126,7 @@ AddBootModuleSymlinksToFloppyBootArchive ahci generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata it8211 $(USB_ONLY)uhci $(USB_ONLY)ohci $(USB_ONLY)ehci - scsi_cd scsi_disk $(USB_ONLY)usb_disk + scsi_cd scsi_disk $(USB_ONLY)usb_disk $(ARM_ONLY)norflash intel session $(SYSTEM_ADD_ONS_FILE_SYSTEMS) $(BOOT_ADD_ONS_NET) diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 1f182c0b8f..b4b6fd85a0 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -335,10 +335,10 @@ SYSTEM_LIBS_ALIASES = ; OPTIONAL_LIBS_ALIASES = - $(HAIKU_FREETYPE_CURRENT_LINK) - $(HAIKU_JPEG_CURRENT_LINK) - $(HAIKU_LIBPNG_CURRENT_LINK) - $(HAIKU_ZLIB_CURRENT_LINK) + libfreetype.so + libjpeg.so + libpng.so + libz.so ; # libfreetype.so links to the current freetype lib diff --git a/docs/develop/ports/arm/todo.txt b/docs/develop/ports/arm/todo.txt index fae21763fc..17cc54bf21 100644 --- a/docs/develop/ports/arm/todo.txt +++ b/docs/develop/ports/arm/todo.txt @@ -1,4 +1,6 @@ * 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 * Fix serial port mapping. Currently kernel uses the haiku_loader identity mapping for it, but this lives in user virtual address space... diff --git a/headers/os/app/Message.h b/headers/os/app/Message.h index c4c72dfc00..bb3a74d671 100644 --- a/headers/os/app/Message.h +++ b/headers/os/app/Message.h @@ -475,6 +475,9 @@ public: status_t SetInt64(const char* name, int64 value); status_t SetUInt64(const char* name, uint64 value); status_t SetPointer(const char* name, const void* value); + status_t SetString(const char* name, const char* string); + status_t SetString(const char* name, + const BString& string); status_t SetFloat(const char* name, float value); status_t SetDouble(const char* name, double value); status_t SetAlignment(const char* name, diff --git a/headers/os/storage/Entry.h b/headers/os/storage/Entry.h index f0c628e49e..60a5a56179 100644 --- a/headers/os/storage/Entry.h +++ b/headers/os/storage/Entry.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010, Haiku, Inc. All Rights Reserved. + * Copyright 2002-2012, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _ENTRY_H @@ -50,6 +50,8 @@ public: status_t InitCheck() const; bool Exists() const; + const char* Name() const; + virtual status_t GetStat(struct stat* stat) const; status_t SetTo(const BDirectory* dir, const char* path, diff --git a/headers/private/kernel/arch/arm/arch_cpu.h b/headers/private/kernel/arch/arm/arch_cpu.h index 34364a8004..a70398aa64 100644 --- a/headers/private/kernel/arch/arm/arch_cpu.h +++ b/headers/private/kernel/arch/arm/arch_cpu.h @@ -33,14 +33,29 @@ struct iframe { uint32 pc; } _PACKED; -typedef struct arch_cpu_info { -} arch_cpu_info; +/**! Values for arch_cpu_info.arch */ +enum { + ARCH_ARM_PRE_ARM7, + ARCH_ARM_v3, + ARCH_ARM_v4, + ARCH_ARM_v4T, + ARCH_ARM_v5, + ARCH_ARM_v5T, + ARCH_ARM_v5TE, + ARCH_ARM_v5TEJ, + ARCH_ARM_v6 +}; -extern int arch_cpu_type; -extern int arch_fpu_type; -extern int arch_mmu_type; -extern int arch_platform; -extern int arch_machine; +typedef struct arch_cpu_info { + /* For a detailed interpretation of these values, + see "The System Control coprocessor", + "Main ID register" in your ARM ARM */ + int implementor; + int part_number; + int revision; + int variant; + int arch; +} arch_cpu_info; #ifdef __cplusplus extern "C" { diff --git a/headers/private/kernel/boot/platform/u-boot/platform_stage2_args.h b/headers/private/kernel/boot/platform/u-boot/platform_stage2_args.h index d47bbb3c66..966fd1761e 100644 --- a/headers/private/kernel/boot/platform/u-boot/platform_stage2_args.h +++ b/headers/private/kernel/boot/platform/u-boot/platform_stage2_args.h @@ -12,6 +12,8 @@ struct platform_stage2_args { void *boot_tgz_data; uint32 boot_tgz_size; + void *fdt_data; + uint32 fdt_size; }; #endif /* KERNEL_BOOT_PLATFORM_UBOOT_STAGE2_H */ diff --git a/headers/private/shared/AboutWindow.h b/headers/private/shared/AboutWindow.h index da7d5c8e37..6dcaa77845 100644 --- a/headers/private/shared/AboutWindow.h +++ b/headers/private/shared/AboutWindow.h @@ -1,28 +1,45 @@ /* - * Copyright 2007-2009 Haiku, Inc. + * Copyright 2007-2012 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: - * Ryan Leavengood, leavengood@gmail.com + * Ryan Leavengood + * John Scipione */ #ifndef B_ABOUT_WINDOW_H #define B_ABOUT_WINDOW_H -#include +#include +#include +#include -class BAboutWindow { - public: - BAboutWindow(const char *appName, int32 firstCopyrightYear, - const char **authors, const char *extraInfo = NULL); - virtual ~BAboutWindow(); +class AboutView; +class BPoint; +class BHandler; - void Show(); +class BAboutWindow : public BWindow { + public: + BAboutWindow(const char* appName, + const char* signature); + virtual ~BAboutWindow(); - private: - BString* fAppName; - BString* fText; + virtual bool QuitRequested(); + + BPoint AboutPosition(float width, float height); + void AddDescription(const char* description); + void AddCopyright(int32 firstCopyrightYear, + const char* copyrightHolder, + const char** extraCopyrights = NULL); + void AddAuthors(const char** authors); + void AddSpecialThanks(const char** thanks); + void AddVersionHistory(const char** history); + void AddExtraInfo(const char* extraInfo); + + private: + AboutView* fAboutView; + BHandler* fCaller; }; #endif // B_ABOUT_WINDOW_H diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp index 0d019fa265..e778ffcbac 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp @@ -1011,6 +1011,7 @@ TRACE("build output tree: %suse mixer\n", useMixer ? "" : "don't "); int device = CONF_DEFAULT_DEVICE(widget.d.pin.config); if (device != PIN_DEV_HEAD_PHONE_OUT + && device != PIN_DEV_DIGITAL_OTHER_OUT && device != PIN_DEV_SPEAKER && device != PIN_DEV_LINE_OUT) continue; diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp index 6d75b06e1e..2f281c3909 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp @@ -770,6 +770,14 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream, hda_send_verbs(codec, verb, response, 2); //channelNum += 2; // TODO stereo widget ? Every output gets the same stream for now dprintf("%ld ", stream->io_widgets[i]); + + hda_widget* widget = hda_audio_group_get_widget(audioGroup, + stream->io_widgets[i]); + if ((widget->capabilities.audio & AUDIO_CAP_DIGITAL) != 0) { + verb[0] = MAKE_VERB(codec->addr, stream->io_widgets[i], + VID_SET_DIGITAL_CONVERTER_CONTROL1, format); + hda_send_verbs(codec, verb, response, 1); + } } dprintf("\n"); diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp index 0c50f8b1b0..6f1a5e273f 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp @@ -892,12 +892,14 @@ get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data) || data->return_record_buffers < STREAM_MIN_BUFFERS) data->return_record_buffers = STREAM_MIN_BUFFERS; - if (data->return_playback_buffer_size == 0) { + if (data->return_playback_buffer_size == 0 + && audioGroup->playback_stream != NULL) { data->return_playback_buffer_size = default_buffer_length_for_rate( audioGroup->playback_stream->sample_rate); } - if (data->return_record_buffer_size == 0) { + if (data->return_record_buffer_size == 0 + && audioGroup->record_stream != NULL) { data->return_record_buffer_size = default_buffer_length_for_rate( audioGroup->record_stream->sample_rate); } diff --git a/src/add-ons/kernel/drivers/disk/Jamfile b/src/add-ons/kernel/drivers/disk/Jamfile index 989aa4d3b9..d6ce88a04a 100644 --- a/src/add-ons/kernel/drivers/disk/Jamfile +++ b/src/add-ons/kernel/drivers/disk/Jamfile @@ -1,6 +1,7 @@ SubDir HAIKU_TOP src add-ons kernel drivers disk ; SubInclude HAIKU_TOP src add-ons kernel drivers disk floppy ; +SubInclude HAIKU_TOP src add-ons kernel drivers disk norflash ; SubInclude HAIKU_TOP src add-ons kernel drivers disk scsi ; SubInclude HAIKU_TOP src add-ons kernel drivers disk usb ; SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual ; diff --git a/src/add-ons/kernel/drivers/disk/norflash/Jamfile b/src/add-ons/kernel/drivers/disk/norflash/Jamfile new file mode 100644 index 0000000000..2294d8d5bc --- /dev/null +++ b/src/add-ons/kernel/drivers/disk/norflash/Jamfile @@ -0,0 +1,10 @@ +SubDir HAIKU_TOP src add-ons kernel drivers disk norflash ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +UsePrivateHeaders drivers kernel ; + +KernelAddon norflash : + norflash.cpp +; + diff --git a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp new file mode 100644 index 0000000000..cfd8c1fff9 --- /dev/null +++ b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp @@ -0,0 +1,298 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ithamar R. Adema + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include + +//#define TRACE_NORFLASH +#ifdef TRACE_NORFLASH +#define TRACE(x...) dprintf("nor: " x) +#else +#define TRACE(x...) +#endif + +#define NORFLASH_DEVICE_MODULE_NAME "drivers/disk/norflash/device_v1" +#define NORFLASH_DRIVER_MODULE_NAME "drivers/disk/norflash/driver_v1" + +#define NORFLASH_ADDR 0x00000000 + +struct nor_driver_info { + device_node *node; + size_t blocksize; + size_t totalsize; + + area_id id; + void *mapped; +}; + +static device_manager_info* sDeviceManager; + +static const char *sTabTab = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; +#define DS "%.*s" +#define DA depth - 1, sTabTab + +static void +dump_hex(const char *data, int32 len, int depth = 1) +{ + char str[128]; + char astr[32]; + char *p; + int l; + int i; + + for (i = 0; i < len; ) { + p = str; + l = sizeof(str); + for (; i < len && (p == str || (i % 16 != 0)); i++) { + snprintf(p, l - 1, "%02x ", data[i]); + l -= strlen(p); + p += strlen(p); + astr[i % 16] = isprint(data[i]) ? data[i] : '.'; + astr[i % 16] = isprint(data[i]) ? data[i] : '.'; + astr[(i % 16) + 1] = '\0'; + } + dprintf(DS" %-48.48s %s\n", DA, str, astr); + } +} + + +static status_t +nor_init_device(void* _info, void** _cookie) +{ + TRACE("init_device\n"); + nor_driver_info* info = (nor_driver_info*)_info; + + info->mapped = NULL; + info->blocksize = 128 * 1024; + info->totalsize = info->blocksize * 256; + + info->id = map_physical_memory("NORFlash", NORFLASH_ADDR, info->totalsize, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &info->mapped); + if (info->id < 0) + return info->id; + + *_cookie = info; + return B_OK; +} + + +static void +nor_uninit_device(void* _cookie) +{ + TRACE("uninit_device\n"); + nor_driver_info* info = (nor_driver_info*)_cookie; + if (info) + delete_area(info->id); +} + + +static status_t +nor_open(void *deviceCookie, const char *path, int openMode, + void **_cookie) +{ + TRACE("open(%s)\n", path); + *_cookie = deviceCookie; + return B_OK; +} + + +static status_t +nor_close(void *_cookie) +{ + TRACE("close()\n"); + return B_OK; +} + + +static status_t +nor_free(void *_cookie) +{ + TRACE("free()\n"); + return B_OK; +} + + +static status_t +nor_ioctl(void *cookie, uint32 op, void *buffer, size_t length) +{ + nor_driver_info* info = (nor_driver_info*)cookie; + TRACE("ioctl(%ld,%lu)\n", op, length); + + switch(op) { + case B_GET_GEOMETRY: + { + device_geometry *deviceGeometry = (device_geometry*)buffer; + deviceGeometry->removable = false; + deviceGeometry->bytes_per_sector = info->blocksize; + deviceGeometry->sectors_per_track = info->totalsize / info->blocksize; + deviceGeometry->cylinder_count = 1; + deviceGeometry->head_count = 1; + deviceGeometry->device_type = B_DISK; + deviceGeometry->removable = false; + deviceGeometry->read_only = true; + deviceGeometry->write_once = false; + return B_OK; + } + break; + case B_GET_DEVICE_NAME: + strlcpy((char*)buffer, "NORFlash", length); + break; + } + + return B_ERROR; +} + + +static status_t +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); + + if (position + *numbytes > info->totalsize) + *numbytes = info->totalsize - (position + *numbytes); + + memcpy(data, info->mapped + position, *numbytes); + +#ifdef TRACE_NORFLASH + dump_hex((const char*)(info->mapped + position), *numbytes, 1); +#endif + + return B_OK; +} + + +static status_t +nor_write(void *_cookie, off_t position, const void *data, size_t *numbytes) +{ + TRACE("write(%Ld,%lu)\n", position, *numbytes); + *numbytes = 0; + return B_ERROR; +} + + +static float +nor_supports_device(device_node *parent) +{ + TRACE("supports_device\n"); + return 0.6; +} + + +static status_t +nor_register_device(device_node *node) +{ + TRACE("register_device\n"); + // ready to register + device_attr attrs[] = { + { NULL } + }; + + return sDeviceManager->register_node(node, NORFLASH_DRIVER_MODULE_NAME, + attrs, NULL, NULL); +} + + +static status_t +nor_init_driver(device_node *node, void **cookie) +{ + TRACE("init_driver\n"); + + nor_driver_info* info = (nor_driver_info*)malloc(sizeof(nor_driver_info)); + if (info == NULL) + return B_NO_MEMORY; + + memset(info, 0, sizeof(*info)); + + info->node = node; + + *cookie = info; + return B_OK; +} + + +static void +nor_uninit_driver(void *_cookie) +{ + TRACE("uninit_driver\n"); + nor_driver_info* info = (nor_driver_info*)_cookie; + free(info); +} + + +static status_t +nor_register_child_devices(void* _cookie) +{ + TRACE("register_child_devices\n"); + nor_driver_info* info = (nor_driver_info*)_cookie; + status_t status; + + status = sDeviceManager->publish_device(info->node, "disk/nor/0/raw", + NORFLASH_DEVICE_MODULE_NAME); + + return status; +} + +struct device_module_info sNORFlashDiskDevice = { + { + NORFLASH_DEVICE_MODULE_NAME, + 0, + NULL + }, + + nor_init_device, + nor_uninit_device, + NULL, //nor_remove, + + nor_open, + nor_close, + nor_free, + nor_read, + nor_write, + NULL, // nor_io, + nor_ioctl, + + NULL, // select + NULL, // deselect +}; + + + +struct driver_module_info sNORFlashDiskDriver = { + { + NORFLASH_DRIVER_MODULE_NAME, + 0, + NULL + }, + + nor_supports_device, + nor_register_device, + nor_init_driver, + nor_uninit_driver, + nor_register_child_devices, + NULL, // rescan + NULL, // removed +}; + +module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager }, + { } +}; + +module_info* modules[] = { + (module_info*)&sNORFlashDiskDriver, + (module_info*)&sNORFlashDiskDevice, + NULL +}; diff --git a/src/apps/activitymonitor/ActivityMonitor.cpp b/src/apps/activitymonitor/ActivityMonitor.cpp index cf9ba52f16..0db3cd1060 100644 --- a/src/apps/activitymonitor/ActivityMonitor.cpp +++ b/src/apps/activitymonitor/ActivityMonitor.cpp @@ -8,17 +8,19 @@ #include -#include #include #include "ActivityWindow.h" + +const char* kAppName = B_TRANSLATE_SYSTEM_NAME("ActivityMonitor"); const char* kSignature = "application/x-vnd.Haiku-ActivityMonitor"; ActivityMonitor::ActivityMonitor() : BApplication(kSignature) { + fWindow = new ActivityWindow(); } @@ -30,7 +32,6 @@ ActivityMonitor::~ActivityMonitor() void ActivityMonitor::ReadyToRun() { - fWindow = new ActivityWindow(); fWindow->Show(); } @@ -52,20 +53,6 @@ ActivityMonitor::MessageReceived(BMessage* message) void ActivityMonitor::AboutRequested() { - ShowAbout(); -} - - -/*static*/ void -ActivityMonitor::ShowAbout() -{ - const char* kAuthors[] = { - "Axel Dörfler", - NULL - }; - - BAboutWindow aboutWindow(B_TRANSLATE_SYSTEM_NAME("ActivityMonitor"), 2008, kAuthors); - aboutWindow.Show(); } diff --git a/src/apps/activitymonitor/ActivityMonitor.h b/src/apps/activitymonitor/ActivityMonitor.h index 7ac0fd3bb1..036acb5559 100644 --- a/src/apps/activitymonitor/ActivityMonitor.h +++ b/src/apps/activitymonitor/ActivityMonitor.h @@ -9,8 +9,9 @@ #include #include -class BMessage; + class ActivityWindow; +class BMessage; #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "ActivityWindow" @@ -28,8 +29,6 @@ public: virtual void AboutRequested(); - static void ShowAbout(); - private: ActivityWindow* fWindow; }; diff --git a/src/apps/activitymonitor/ActivityView.cpp b/src/apps/activitymonitor/ActivityView.cpp index e3db9f8845..fc4f32efa0 100644 --- a/src/apps/activitymonitor/ActivityView.cpp +++ b/src/apps/activitymonitor/ActivityView.cpp @@ -12,6 +12,7 @@ #include #ifdef __HAIKU__ +# include # include # include #endif @@ -175,6 +176,7 @@ const uint32 kMsgToggleDataSource = 'tgds'; const uint32 kMsgToggleLegend = 'tglg'; const uint32 kMsgUpdateResolution = 'ures'; +extern const char* kAppName; extern const char* kSignature; @@ -598,6 +600,10 @@ ActivityView::~ActivityView() { delete fOffscreen; delete fSystemInfoHandler; + + // replicant deleted, destroy the about window + if (fAboutWindow != NULL) + fAboutWindow->Quit(); } @@ -641,6 +647,8 @@ ActivityView::_Init(const BMessage* settings) const char* name; for (int32 i = 0; settings->FindString("source", i, &name) == B_OK; i++) AddDataSource(DataSource::FindSource(name), settings); + + fAboutWindow = NULL; } @@ -1104,7 +1112,21 @@ ActivityView::MessageReceived(BMessage* message) switch (message->what) { case B_ABOUT_REQUESTED: - ActivityMonitor::ShowAbout(); + if (fAboutWindow == NULL) { + const char* authors[] = { + "Axel Dörfler", + NULL + }; + + fAboutWindow = new BAboutWindow(kAppName, kSignature); + fAboutWindow->AddCopyright(2008, "Haiku, Inc."); + fAboutWindow->AddAuthors(authors); + fAboutWindow->Show(); + } else if (fAboutWindow->IsHidden()) + fAboutWindow->Show(); + else + fAboutWindow->Activate(); + break; case kMsgUpdateResolution: diff --git a/src/apps/activitymonitor/ActivityView.h b/src/apps/activitymonitor/ActivityView.h index 5ffa336312..0e1ccf6520 100644 --- a/src/apps/activitymonitor/ActivityView.h +++ b/src/apps/activitymonitor/ActivityView.h @@ -16,6 +16,8 @@ #include "CircularBuffer.h" #include "DataSource.h" + +class BAboutWindow; class BBitmap; class BMessageRunner; class Scale; @@ -23,7 +25,6 @@ class SystemInfoHandler; class ViewHistory; struct data_item; - class DataHistory { public: DataHistory(bigtime_t memorize, bigtime_t interval); @@ -145,6 +146,8 @@ private: int32 fOriginalResolution; SystemInfoHandler* fSystemInfoHandler; std::map fScales; + + BAboutWindow* fAboutWindow; }; #endif // ACTIVITY_VIEW_H diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index 845af2e2f7..998d3be7f4 100644 --- a/src/apps/debugger/arch/Architecture.h +++ b/src/apps/debugger/arch/Architecture.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef ARCHITECTURE_H @@ -38,6 +38,13 @@ enum { }; +enum { + WATCHPOINT_CAPABILITY_FLAG_READ = 1, + WATCHPOINT_CAPABILITY_FLAG_WRITE = 2, + WATCHPOINT_CAPABILITY_FLAG_READ_WRITE = 4 +}; + + class Architecture : public BReferenceable { public: Architecture(TeamMemory* teamMemory, @@ -105,6 +112,12 @@ public: bool useExistingTrace = false); // team is not locked + virtual status_t GetWatchpointDebugCapabilities( + int32& _maxRegisterCount, + int32& _maxBytesPerRegister, + uint8& _watchpointCapabilityFlags) = 0; + + protected: TeamMemory* fTeamMemory; uint8 fAddressSize; diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index 9fd80cfa7a..bc2e075684 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.cpp +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -611,6 +611,24 @@ ArchitectureX86::GetInstructionInfo(target_addr_t address, } +status_t +ArchitectureX86::GetWatchpointDebugCapabilities(int32& _maxRegisterCount, + int32& _maxBytesPerRegister, uint8& _watchpointCapabilityFlags) +{ + // while x86 technically has 4 hardware debug registers, one is reserved by + // the kernel, and one is required for breakpoint support, which leaves + // two available for watchpoints. + _maxRegisterCount = 2; + _maxBytesPerRegister = 4; + + // x86 only supports write and read/write watchpoints. + _watchpointCapabilityFlags = WATCHPOINT_CAPABILITY_FLAG_WRITE + | WATCHPOINT_CAPABILITY_FLAG_READ_WRITE; + + return B_OK; +} + + void ArchitectureX86::_AddRegister(int32 index, const char* name, uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved) diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h index 33369aa5db..48e849c502 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.h +++ b/src/apps/debugger/arch/x86/ArchitectureX86.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef ARCHITECTURE_X86_H @@ -23,7 +23,7 @@ public: virtual status_t Init(); - virtual int32 StackGrowthDirection() const; + virtual int32 StackGrowthDirection() const; virtual int32 CountRegisters() const; virtual const Register* Registers() const; @@ -61,6 +61,11 @@ public: virtual status_t GetInstructionInfo(target_addr_t address, InstructionInfo& _info); + virtual status_t GetWatchpointDebugCapabilities( + int32& _maxRegisterCount, + int32& _maxBytesPerRegister, + uint8& _watchpointCapabilityFlags); + private: struct ToDwarfRegisterMap; struct FromDwarfRegisterMap; diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index 862895233b..9042ff3e16 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -261,8 +261,9 @@ TeamWindow::MessageReceived(BMessage* message) } try { - WatchPromptWindow* window = WatchPromptWindow::Create(address, - type, length, fListener); + WatchPromptWindow* window = WatchPromptWindow::Create( + fTeam->GetArchitecture(), address, type, length, + fListener); window->Show(); } catch (...) { // TODO: notify user diff --git a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp index 2718ce80ff..8464582e1f 100644 --- a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp @@ -15,38 +15,43 @@ #include +#include "Architecture.h" #include "MessageCodes.h" #include "UserInterface.h" #include "Watchpoint.h" -WatchPromptWindow::WatchPromptWindow(target_addr_t address, uint32 type, - int32 length, UserInterfaceListener* listener) +WatchPromptWindow::WatchPromptWindow(Architecture* architecture, + target_addr_t address, uint32 type, int32 length, + UserInterfaceListener* listener) : BWindow(BRect(), "Edit Watchpoint", B_FLOATING_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), fInitialAddress(address), fInitialType(type), fInitialLength(length), + fArchitecture(architecture), fAddressInput(NULL), fLengthInput(NULL), fTypeField(NULL), fListener(listener) { + fArchitecture->AcquireReference(); } WatchPromptWindow::~WatchPromptWindow() { + fArchitecture->ReleaseReference(); } WatchPromptWindow* -WatchPromptWindow::Create(target_addr_t address, uint32 type, int32 length, - UserInterfaceListener* listener) +WatchPromptWindow::Create(Architecture* architecture, target_addr_t address, + uint32 type, int32 length, UserInterfaceListener* listener) { - WatchPromptWindow* self = new WatchPromptWindow(address, type, length, - listener); + WatchPromptWindow* self = new WatchPromptWindow(architecture, address, + type, length, listener); try { self->_Init(); @@ -69,10 +74,29 @@ WatchPromptWindow::_Init() text.SetToFormat("%" B_PRId32, fInitialLength); fLengthInput = new BTextControl("Length:", text, NULL); + int32 maxDebugRegisters = 0; + int32 maxBytesPerRegister = 0; + uint8 debugCapabilityFlags = 0; + fArchitecture->GetWatchpointDebugCapabilities(maxDebugRegisters, + maxBytesPerRegister, debugCapabilityFlags); + BMenu* typeMenu = new BMenu("Watch Type"); - typeMenu->AddItem(new BMenuItem("Read", NULL)); - typeMenu->AddItem(new BMenuItem("Write", NULL)); - typeMenu->AddItem(new BMenuItem("Read/Write", NULL)); + + BMenuItem* watchTypeItem = new BMenuItem("Read", NULL); + watchTypeItem->SetEnabled( + (debugCapabilityFlags & WATCHPOINT_CAPABILITY_FLAG_READ) != 0); + typeMenu->AddItem(watchTypeItem); + + watchTypeItem = new BMenuItem("Write", NULL); + watchTypeItem->SetEnabled( + (debugCapabilityFlags & WATCHPOINT_CAPABILITY_FLAG_WRITE) != 0); + typeMenu->AddItem(watchTypeItem); + + watchTypeItem = new BMenuItem("Read/Write", NULL); + watchTypeItem->SetEnabled( + (debugCapabilityFlags & WATCHPOINT_CAPABILITY_FLAG_READ_WRITE) != 0); + typeMenu->AddItem(watchTypeItem); + fTypeField = new BMenuField("Type:", typeMenu); BLayoutItem* labelItem = fTypeField->CreateLabelLayoutItem(); labelItem->View()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); diff --git a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.h b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.h index 465fdd696c..5854ca8e4e 100644 --- a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.h @@ -11,6 +11,7 @@ #include "types/Types.h" +class Architecture; class BTextControl; class Watchpoint; class BMenuField; @@ -20,14 +21,15 @@ class UserInterfaceListener; class WatchPromptWindow : public BWindow { public: - // edit existing watchpoint - WatchPromptWindow(target_addr_t address, - uint32 type, int32 length, + WatchPromptWindow(Architecture* architecture, + target_addr_t address, uint32 type, + int32 length, UserInterfaceListener* listener); ~WatchPromptWindow(); - static WatchPromptWindow* Create(target_addr_t address, uint32 type, + static WatchPromptWindow* Create(Architecture* architecture, + target_addr_t address, uint32 type, int32 length, UserInterfaceListener* listener); // throws @@ -45,6 +47,7 @@ private: target_addr_t fInitialAddress; uint32 fInitialType; int32 fInitialLength; + Architecture* fArchitecture; BTextControl* fAddressInput; BTextControl* fLengthInput; BMenuField* fTypeField; diff --git a/src/apps/deskbar/BarMenuBar.cpp b/src/apps/deskbar/BarMenuBar.cpp index bd093ae8e6..ce4932edc2 100644 --- a/src/apps/deskbar/BarMenuBar.cpp +++ b/src/apps/deskbar/BarMenuBar.cpp @@ -51,6 +51,8 @@ All rights reserved. #include "TeamMenu.h" +const float kSepItemWidth = 5.0f; + TBarMenuBar::TBarMenuBar(TBarView* bar, BRect frame, const char* name) : BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false), fBarView(bar), @@ -86,11 +88,15 @@ TBarMenuBar::SmartResize(float width, float height) width -= 1; - int32 count = CountItems(); - if (fDeskbarMenuItem) - fDeskbarMenuItem->SetWidthHeight(width / count, height); - if (fAppListMenuItem) - fAppListMenuItem->SetWidthHeight(width / count, height); + if (fSeparatorItem) + fDeskbarMenuItem->SetWidthHeight(width - kSepItemWidth, height); + else { + int32 count = CountItems(); + if (fDeskbarMenuItem) + fDeskbarMenuItem->SetWidthHeight(width / count, height); + if (fAppListMenuItem) + fAppListMenuItem->SetWidthHeight(width / count, height); + } InvalidateLayout(); } @@ -130,17 +136,51 @@ TBarMenuBar::RemoveTeamMenu() void -TBarMenuBar::Draw(BRect rect) +TBarMenuBar::AddSeperatorItem() { - // want to skip the fancy BMenuBar drawing code. - BMenu::Draw(rect); + if (CountItems() > 1) + return; + + BRect frame(Frame()); + delete fSeparatorItem; + + fSeparatorItem = new TTeamMenuItem(kSepItemWidth, + frame.Height() - 2, false); + AddItem(fSeparatorItem); + fSeparatorItem->SetEnabled(false); + SmartResize(frame.Width() - 1.0f, frame.Height()); } void -TBarMenuBar::DrawBackground(BRect rect) +TBarMenuBar::RemoveSeperatorItem() { - BMenu::DrawBackground(rect); + if (CountItems() < 2) + return; + + if (fSeparatorItem) { + RemoveItem((BMenuItem*)fSeparatorItem); + delete fSeparatorItem; + fSeparatorItem = NULL; + } + + BRect frame = Frame(); + SmartResize(frame.Width(), frame.Height()); +} + + +void +TBarMenuBar::Draw(BRect updateRect) +{ + // want to skip the fancy BMenuBar drawing code. + BMenu::Draw(updateRect); +} + + +void +TBarMenuBar::DrawBackground(BRect updateRect) +{ + BMenu::DrawBackground(updateRect); } diff --git a/src/apps/deskbar/BarMenuBar.h b/src/apps/deskbar/BarMenuBar.h index a10630dbfc..f691a903a5 100644 --- a/src/apps/deskbar/BarMenuBar.h +++ b/src/apps/deskbar/BarMenuBar.h @@ -63,6 +63,9 @@ class TBarMenuBar : public BMenuBar { void AddTeamMenu(); void RemoveTeamMenu(); + void AddSeperatorItem(); + void RemoveSeperatorItem(); + void InitTrackingHook(bool (* hookfunction)(BMenu*, void*), void* state, bool both = false); @@ -70,6 +73,7 @@ class TBarMenuBar : public BMenuBar { TBarView* fBarView; TBarMenuTitle* fDeskbarMenuItem; TBarMenuTitle* fAppListMenuItem; + TTeamMenuItem* fSeparatorItem; }; diff --git a/src/apps/deskbar/BarView.cpp b/src/apps/deskbar/BarView.cpp index 0bc16d2f6f..07f28782a7 100644 --- a/src/apps/deskbar/BarView.cpp +++ b/src/apps/deskbar/BarView.cpp @@ -58,6 +58,7 @@ All rights reserved. #include "DeskbarUtils.h" #include "ExpandoMenuBar.h" #include "FSUtils.h" +#include "InlineScrollView.h" #include "ResourceSet.h" #include "StatusView.h" #include "TeamMenuItem.h" @@ -70,6 +71,7 @@ const int32 kDefaultRecentAppCount = 10; const int32 kMenuTrackMargin = 20; const uint32 kUpdateOrientation = 'UpOr'; +const float kSepItemWidth = 5.0f; class BarViewMessageFilter : public BMessageFilter @@ -130,6 +132,7 @@ BarViewMessageFilter::Filter(BMessage* message, BHandler** target) TBarView::TBarView(BRect frame, bool vertical, bool left, bool top, uint32 state, float) : BView(frame, "BarView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW), + fInlineScrollView(NULL), fBarMenuBar(NULL), fExpando(NULL), fTrayLocation(1), @@ -347,47 +350,47 @@ TBarView::MouseDown(BPoint where) void TBarView::PlaceDeskbarMenu() { - // top or bottom, full - if (!fVertical && fBarMenuBar) { - fBarMenuBar->RemoveSelf(); - delete fBarMenuBar; - fBarMenuBar = NULL; + // Calculate the size of the deskbar menu + BRect menuFrame(Bounds()); + if (fVertical) + menuFrame.bottom = menuFrame.top + kMenuBarHeight; + else { + menuFrame.bottom = menuFrame.top + + static_cast(be_app)->IconSize() + 4; } - // top or bottom expando mode has Be menu built in for tracking - // only for vertical mini or expanded - // mini mode will have team menu added as part of BarMenuBar - if (fVertical && !fBarMenuBar) { + if (fBarMenuBar == NULL) { // create the Be menu - BRect mbarFrame(Bounds()); - mbarFrame.bottom = mbarFrame.top + kMenuBarHeight; - fBarMenuBar = new TBarMenuBar(this, mbarFrame, "BarMenuBar"); + fBarMenuBar = new TBarMenuBar(this, menuFrame, "BarMenuBar"); AddChild(fBarMenuBar); - } - - // if there isn't a bemenu at this point, - // DB should be in top/bottom mode, else error - if (!fBarMenuBar) - return; + } else + fBarMenuBar->SmartResize(-1, -1); float width = sMinimumWindowWidth; BPoint loc(B_ORIGIN); - BRect menuFrame(fBarMenuBar->Frame()); + if (fState == kFullState) { fBarMenuBar->RemoveTeamMenu(); + fBarMenuBar->RemoveSeperatorItem(); // TODO: Magic constants need explanation width = 8 + 16 + 8; + fBarMenuBar->SmartResize(width, menuFrame.Height()); loc = Bounds().LeftTop(); } else if (fState == kExpandoState) { - // shows apps below tray fBarMenuBar->RemoveTeamMenu(); - if (fVertical) + if (fVertical) { + // shows apps below tray + fBarMenuBar->RemoveSeperatorItem(); width += 1; - else - width = floorf(width) / 2; + } else { + // shows apps to the right of bemenu + fBarMenuBar->AddSeperatorItem(); + width = floorf(width) / 2 + kSepItemWidth; + } loc = Bounds().LeftTop(); } else { // mini mode, DeskbarMenu next to team menu + fBarMenuBar->RemoveSeperatorItem(); fBarMenuBar->AddTeamMenu(); } @@ -441,9 +444,16 @@ TBarView::PlaceTray(bool vertSwap, bool leftSwap) void TBarView::PlaceApplicationBar() { + SaveExpandedItems(); + + if (fInlineScrollView != NULL) { + fInlineScrollView->DetachScrollers(); + fInlineScrollView->RemoveSelf(); + delete fInlineScrollView; + fInlineScrollView = NULL; + } + if (fExpando != NULL) { - SaveExpandedItems(); - fExpando->RemoveSelf(); delete fExpando; fExpando = NULL; } @@ -458,6 +468,7 @@ TBarView::PlaceApplicationBar() } BRect expandoFrame(0, 0, 0, 0); + BRect menuScrollFrame(0, 0, 0, 0); if (fVertical) { // top left/right if (fTrayLocation != 0) @@ -470,28 +481,45 @@ TBarView::PlaceApplicationBar() expandoFrame.right = fBarMenuBar->Frame().Width(); else expandoFrame.right = sMinimumWindowWidth; + + menuScrollFrame = expandoFrame; + menuScrollFrame.bottom = screenFrame.bottom; } else { // top or bottom expandoFrame.top = 0; int32 iconSize = static_cast(be_app)->IconSize(); expandoFrame.bottom = iconSize + 4; - if (fTrayLocation != 0) - expandoFrame.right = fDragRegion->Frame().left - 1; - else + + if (fBarMenuBar != NULL) + expandoFrame.left = fBarMenuBar->Frame().Width(); + + if (fTrayLocation != 0 && fDragRegion != NULL) { + expandoFrame.right = screenFrame.Width() + - fDragRegion->Frame().Width() - 1; + } else expandoFrame.right = screenFrame.Width(); + + menuScrollFrame = expandoFrame; } bool hideLabels = ((TBarApp*)be_app)->Settings()->hideLabels; fExpando = new TExpandoMenuBar(this, expandoFrame, "ExpandoMenuBar", fVertical, !hideLabels && fState != kFullState); - AddChild(fExpando); + + fInlineScrollView = new TInlineScrollView(menuScrollFrame, fExpando, + fVertical ? B_VERTICAL : B_HORIZONTAL); + AddChild(fInlineScrollView); if (fVertical) ExpandItems(); SizeWindow(screenFrame); PositionWindow(screenFrame); + fExpando->DoLayout(); + // force menu to autosize + CheckForScrolling(); + Window()->UpdateIfNeeded(); Invalidate(); } @@ -522,7 +550,12 @@ TBarView::GetPreferredWindowSize(BRect screenFrame, float* width, float* height) } else if (fState == kExpandoState) { if (fVertical) { // top left or right - windowHeight = fExpando->Frame().bottom; + if (fTrayLocation != 0) + windowHeight = fDragRegion->Frame().bottom + 1; + else + windowHeight = fBarMenuBar->Frame().bottom + 1; + + windowHeight += fExpando->Bounds().Height(); } else { // top or bottom, full fExpando->CheckItemSizes(0); @@ -549,8 +582,6 @@ TBarView::SizeWindow(BRect screenFrame) float windowWidth, windowHeight; GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight); Window()->ResizeTo(windowWidth, windowHeight); - if (fExpando) - fExpando->CheckForSizeOverrun(); } @@ -577,6 +608,18 @@ TBarView::PositionWindow(BRect screenFrame) } +void +TBarView::CheckForScrolling() +{ + if (fInlineScrollView != NULL && fExpando != NULL) { + if (fExpando->CheckForSizeOverrun()) + fInlineScrollView->AttachScrollers(); + else + fInlineScrollView->DetachScrollers(); + } +} + + void TBarView::SaveSettings() { @@ -678,8 +721,6 @@ TBarView::ExpandItems() // Clean up the expanded items list RemoveExpandedItems(); - - fExpando->SizeWindow(); } diff --git a/src/apps/deskbar/BarView.h b/src/apps/deskbar/BarView.h index f375c872d4..d04586775e 100644 --- a/src/apps/deskbar/BarView.h +++ b/src/apps/deskbar/BarView.h @@ -65,12 +65,12 @@ const float kStatusHeight = 22.0f; const float kHiddenDimension = 1.0f; const float kMaxPreventHidingDist = 80.0f; - class BShelf; class TBarMenuBar; class TExpandoMenuBar; class TReplicantTray; class TDragRegion; +class TInlineScrollView; class TTeamMenuItem; @@ -148,6 +148,8 @@ class TBarView : public BView { void PositionWindow(BRect screenFrame); void AddExpandedItem(const char* signature); + void CheckForScrolling(); + TExpandoMenuBar* ExpandoMenuBar() const; TBarMenuBar* BarMenuBar() const; TDragRegion* DragRegion() const { return fDragRegion; } @@ -168,6 +170,7 @@ class TBarView : public BView { void ExpandItems(); void _ChangeState(BMessage* message); + TInlineScrollView* fInlineScrollView; TBarMenuBar* fBarMenuBar; TExpandoMenuBar* fExpando; diff --git a/src/apps/deskbar/ExpandoMenuBar.cpp b/src/apps/deskbar/ExpandoMenuBar.cpp index 15d724fd58..91f4cfa2be 100644 --- a/src/apps/deskbar/ExpandoMenuBar.cpp +++ b/src/apps/deskbar/ExpandoMenuBar.cpp @@ -54,6 +54,7 @@ All rights reserved. #include "BarWindow.h" #include "DeskbarMenu.h" #include "DeskbarUtils.h" +#include "InlineScrollView.h" #include "ResourceSet.h" #include "ShowHideMenuItem.h" #include "StatusView.h" @@ -62,7 +63,7 @@ All rights reserved. #include "WindowMenuItem.h" -const float kDefaultDeskbarMenuWidth = 50.0f; +const float kMinMenuItemWidth = 50.0f; const float kSepItemWidth = 5.0f; const float kIconPadding = 8.0f; @@ -78,16 +79,14 @@ TExpandoMenuBar::TExpandoMenuBar(TBarView* bar, BRect frame, const char* name, bool vertical, bool drawLabel) : BMenuBar(frame, name, B_FOLLOW_NONE, - vertical ? B_ITEMS_IN_COLUMN : B_ITEMS_IN_ROW, vertical), + vertical ? B_ITEMS_IN_COLUMN : B_ITEMS_IN_ROW), fVertical(vertical), fOverflow(false), fDrawLabel(drawLabel), - fIsScrolling(false), fShowTeamExpander(static_cast(be_app)->Settings()->superExpando), fExpandNewTeams(static_cast(be_app)->Settings()->expandNewTeams), - fDeskbarMenuWidth(kDefaultDeskbarMenuWidth), + fDeskbarMenuWidth(kMinMenuItemWidth), fBarView(bar), - fFirstApp(0), fPreviousDragTargetItem(NULL), fLastClickItem(NULL) { @@ -137,24 +136,10 @@ TExpandoMenuBar::AttachedToWindow() // top or bottom mode, add deskbar menu and sep for menubar tracking // consistency if (!fVertical) { - TDeskbarMenu* beMenu = new TDeskbarMenu(fBarView); - TBarWindow::SetDeskbarMenu(beMenu); const BBitmap* logoBitmap = AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_LeafLogoBitmap); if (logoBitmap != NULL) fDeskbarMenuWidth = logoBitmap->Bounds().Width() + 16; - - fDeskbarMenuItem = new TBarMenuTitle(fDeskbarMenuWidth, - Frame().Height(), logoBitmap, beMenu, true); - AddItem(fDeskbarMenuItem); - - fSeparatorItem = new TTeamMenuItem(kSepItemWidth, itemHeight, fVertical); - AddItem(fSeparatorItem); - fSeparatorItem->SetEnabled(false); - fFirstApp = 2; - } else { - fDeskbarMenuItem = NULL; - fSeparatorItem = NULL; } if (settings->sortRunningApps) @@ -169,7 +154,7 @@ TExpandoMenuBar::AttachedToWindow() && !strcmp(barInfo->sig, kTrackerSignature)) { AddItem(new TTeamMenuItem(barInfo->teams, barInfo->icon, barInfo->name, barInfo->sig, itemWidth, itemHeight, - fDrawLabel, fVertical), fFirstApp); + fDrawLabel, fVertical), 0); } else { AddItem(new TTeamMenuItem(barInfo->teams, barInfo->icon, barInfo->name, barInfo->sig, itemWidth, itemHeight, @@ -232,7 +217,8 @@ TExpandoMenuBar::MessageReceived(BMessage* message) TTeamMenuItem* item; switch (message->what) { - case B_SOME_APP_LAUNCHED: { + case B_SOME_APP_LAUNCHED: + { BList* teams = NULL; message->FindPointer("teams", (void**)&teams); @@ -262,6 +248,32 @@ TExpandoMenuBar::MessageReceived(BMessage* message) break; } + case B_MOUSE_WHEEL_CHANGED: + { + float deltaY = 0; + message->FindFloat("be:wheel_delta_y", &deltaY); + if (deltaY == 0) + return; + + TInlineScrollView* scrollView + = dynamic_cast(Parent()); + if (scrollView == NULL) + return; + + float largeStep; + float smallStep; + scrollView->GetSteps(&smallStep, &largeStep); + + // pressing the option/command/control key scrolls faster + if (modifiers() & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY)) + deltaY *= largeStep; + else + deltaY *= smallStep; + + scrollView->ScrollBy(deltaY); + break; + } + case kAddTeam: AddTeam(message->FindInt32("team"), message->FindString("sig")); break; @@ -500,20 +512,15 @@ TExpandoMenuBar::MouseUp(BPoint where) bool TExpandoMenuBar::InDeskbarMenu(BPoint loc) const { - if (!fVertical) { - if (fDeskbarMenuItem && fDeskbarMenuItem->Frame().Contains(loc)) - return true; - } else { - TBarWindow* window = dynamic_cast(Window()); - if (window) { - if (TDeskbarMenu* bemenu = window->DeskbarMenu()) { - bool inDeskbarMenu = false; - if (bemenu->LockLooper()) { - inDeskbarMenu = bemenu->Frame().Contains(loc); - bemenu->UnlockLooper(); - } - return inDeskbarMenu; + TBarWindow* window = dynamic_cast(Window()); + if (window) { + if (TDeskbarMenu* bemenu = window->DeskbarMenu()) { + bool inDeskbarMenu = false; + if (bemenu->LockLooper()) { + inDeskbarMenu = bemenu->Frame().Contains(loc); + bemenu->UnlockLooper(); } + return inDeskbarMenu; } } @@ -532,7 +539,7 @@ TExpandoMenuBar::TeamItemAtPoint(BPoint point, BMenuItem** _item) TTeamMenuItem* lastApp = NULL; int32 count = CountItems(); - for (int32 i = fFirstApp; i < count; i++) { + for (int32 i = 0; i < count; i++) { BMenuItem* item = ItemAt(i); if (dynamic_cast(item) != NULL) @@ -578,11 +585,11 @@ TExpandoMenuBar::AddTeam(BList* team, BBitmap* icon, char* name, itemWidth, itemHeight, fDrawLabel, fVertical); if (settings->trackerAlwaysFirst && !strcmp(signature, kTrackerSignature)) - AddItem(item, fFirstApp); + AddItem(item, 0); else if (settings->sortRunningApps) { TTeamMenuItem* teamItem - = dynamic_cast(ItemAt(fFirstApp)); - int32 firstApp = fFirstApp; + = dynamic_cast(ItemAt(0)); + int32 firstApp = 0; // if Tracker should always be the first item, we need to skip it // when sorting in the current item @@ -610,10 +617,9 @@ TExpandoMenuBar::AddTeam(BList* team, BBitmap* icon, char* name, if (fVertical) { if (item && fShowTeamExpander && fExpandNewTeams) item->ToggleExpandState(false); + } - fBarView->SizeWindow(BScreen(Window()).Frame()); - } else - CheckItemSizes(1); + SizeWindow(1); Window()->UpdateIfNeeded(); } @@ -623,7 +629,7 @@ void TExpandoMenuBar::AddTeam(team_id team, const char* signature) { int32 count = CountItems(); - for (int32 i = fFirstApp; i < count; i++) { + for (int32 i = 0; i < count; i++) { // Only add to team menu items if (TTeamMenuItem* item = dynamic_cast(ItemAt(i))) { if (strcasecmp(item->Signature(), signature) == 0) { @@ -640,7 +646,7 @@ void TExpandoMenuBar::RemoveTeam(team_id team, bool partial) { int32 count = CountItems(); - for (int32 i = fFirstApp; i < count; i++) { + for (int32 i = 0; i < count; i++) { if (TTeamMenuItem* item = dynamic_cast(ItemAt(i))) { if (item->Teams()->HasItem((void*)team)) { item->Teams()->RemoveItem(team); @@ -655,14 +661,7 @@ TExpandoMenuBar::RemoveTeam(team_id team, bool partial) RemoveItem(i); - if (fVertical) { - // instead of resizing the window here and there in the - // code the resize method will be centered in one place - // thus, the same behavior (good or bad) will be used - // whereever window sizing is done - fBarView->SizeWindow(BScreen(Window()).Frame()); - } else - CheckItemSizes(-1); + SizeWindow(-1); Window()->UpdateIfNeeded(); @@ -680,63 +679,56 @@ TExpandoMenuBar::CheckItemSizes(int32 delta) if (fBarView->Vertical()) return; + float maxWidth = fBarView->DragRegion()->Frame().left + - fDeskbarMenuWidth - kSepItemWidth; int32 iconSize = static_cast(be_app)->IconSize(); - float maxContentWidth = sMinimumWindowWidth + iconSize - kMinimumIconSize; - - // There are 2 extra items: - // The Be Menu - // The little separator item - int32 count = CountItems() - 2; - float maxWidth = Frame().Width() - fDeskbarMenuWidth - kSepItemWidth * 2; - float fullWidth = maxContentWidth * count + fDeskbarMenuWidth - + kSepItemWidth; float iconOnlyWidth = kIconPadding + iconSize + kIconPadding; + float minItemWidth = fDrawLabel ? iconOnlyWidth + kMinMenuItemWidth + : iconOnlyWidth - kIconPadding; + float maxItemWidth = fDrawLabel ? sMinimumWindowWidth + iconSize + - kMinimumIconSize : iconOnlyWidth; + float menuWidth = maxItemWidth * CountItems() + fDeskbarMenuWidth + + kSepItemWidth; bool reset = false; float newWidth = 0.0f; - if (delta >= 0 && fullWidth > maxWidth) { + if (delta >= 0 && menuWidth > maxWidth) { fOverflow = true; reset = true; - if (fDrawLabel) - newWidth = floorf(maxWidth / count); - else - newWidth = iconOnlyWidth; + newWidth = floorf(maxWidth / CountItems()); } else if (delta < 0 && fOverflow) { reset = true; - if (fullWidth > maxWidth) { - if (fDrawLabel) - newWidth = floorf(maxWidth / count); - else - newWidth = iconOnlyWidth; - } else - newWidth = maxContentWidth; + if (menuWidth > maxWidth) + newWidth = floorf(maxWidth / CountItems()); + else + newWidth = maxItemWidth; } - if (newWidth > maxContentWidth) - newWidth = maxContentWidth; + if (newWidth > maxItemWidth) + newWidth = maxItemWidth; + else if (newWidth < minItemWidth) + newWidth = minItemWidth; if (reset) { SetMaxContentWidth(newWidth); - if (newWidth == maxContentWidth) + if (newWidth == maxItemWidth) fOverflow = false; InvalidateLayout(); - for (int32 index = fFirstApp; ; index++) { + for (int32 index = 0; ; index++) { TTeamMenuItem* item = (TTeamMenuItem*)ItemAt(index); - if (!item) + if (item == NULL) break; - if (!fDrawLabel && newWidth > iconOnlyWidth) { - item->SetOverrideWidth(iconOnlyWidth); - } else { - item->SetOverrideWidth(newWidth); - } + item->SetOverrideWidth(newWidth); } Invalidate(); Window()->UpdateIfNeeded(); } + + fBarView->CheckForScrolling(); } @@ -748,14 +740,14 @@ TExpandoMenuBar::MenuLayout() const void -TExpandoMenuBar::Draw(BRect update) +TExpandoMenuBar::Draw(BRect updateRect) { - BMenu::Draw(update); + BMenu::Draw(updateRect); } void -TExpandoMenuBar::DrawBackground(BRect) +TExpandoMenuBar::DrawBackground(BRect updateRect) { if (fVertical) return; @@ -765,9 +757,9 @@ TExpandoMenuBar::DrawBackground(BRect) rgb_color hilite = tint_color(menuColor, B_DARKEN_1_TINT); rgb_color vlight = tint_color(menuColor, B_LIGHTEN_2_TINT); - int32 last = CountItems() - 1; - if (last >= 0) - bounds.left = ItemAt(last)->Frame().right + 1; + int32 count = CountItems() - 1; + if (count >= 0) + bounds.left = ItemAt(count)->Frame().right + 1; else bounds.left = 0; @@ -794,23 +786,46 @@ TExpandoMenuBar::DrawBackground(BRect) /*! Something to help determine if we are showing too many apps need to add in scrolling functionality. */ -void +bool TExpandoMenuBar::CheckForSizeOverrun() { - BRect screenFrame = (BScreen(Window())).Frame(); + if (fVertical) { + BRect screenFrame = (BScreen(Window())).Frame(); + return Window()->Frame().bottom > screenFrame.bottom; + } - fIsScrolling = fVertical ? Window()->Frame().bottom > screenFrame.bottom - : false; + // horizontal + int32 count = CountItems() - 1; + if (count < 0) + return false; + + int32 iconSize = static_cast(be_app)->IconSize(); + float iconOnlyWidth = kIconPadding + iconSize + kIconPadding; + float minItemWidth = fDrawLabel ? iconOnlyWidth + kMinMenuItemWidth + : iconOnlyWidth - kIconPadding; + float menuWidth = minItemWidth * CountItems() + fDeskbarMenuWidth + + kSepItemWidth; + float maxWidth = fBarView->DragRegion()->Frame().left + - fDeskbarMenuWidth - kSepItemWidth; + + return menuWidth > maxWidth; } void -TExpandoMenuBar::SizeWindow() +TExpandoMenuBar::SizeWindow(int32 delta) { - if (fVertical) - fBarView->SizeWindow(BScreen(Window()).Frame()); - else - CheckItemSizes(1); + // instead of resizing the window here and there in the + // code the resize method will be centered in one place + // thus, the same behavior (good or bad) will be used + // wherever window sizing is done + if (fVertical) { + BRect screenFrame = (BScreen(Window())).Frame(); + fBarView->SizeWindow(screenFrame); + fBarView->PositionWindow(screenFrame); + fBarView->CheckForScrolling(); + } else + CheckItemSizes(delta); } @@ -915,7 +930,7 @@ TExpandoMenuBar::monitor_team_windows(void* arg) if (itemModified || resize) { teamMenu->Invalidate(); if (resize) - teamMenu->SizeWindow(); + teamMenu->SizeWindow(1); } teamMenu->Window()->Unlock(); diff --git a/src/apps/deskbar/ExpandoMenuBar.h b/src/apps/deskbar/ExpandoMenuBar.h index 4eabc96d8d..79f628cda8 100644 --- a/src/apps/deskbar/ExpandoMenuBar.h +++ b/src/apps/deskbar/ExpandoMenuBar.h @@ -82,8 +82,8 @@ class TExpandoMenuBar : public BMenuBar { menu_layout MenuLayout() const; - void SizeWindow(); - void CheckForSizeOverrun(); + void SizeWindow(int32 delta); + bool CheckForSizeOverrun(); private: static int CompareByName(const void* first, const void* second); @@ -98,18 +98,14 @@ class TExpandoMenuBar : public BMenuBar { bool fVertical : 1; bool fOverflow : 1; bool fDrawLabel : 1; - bool fIsScrolling : 1; bool fShowTeamExpander : 1; bool fExpandNewTeams : 1; float fDeskbarMenuWidth; TBarView* fBarView; - int32 fFirstApp; - TBarMenuTitle* fDeskbarMenuItem; - TTeamMenuItem* fSeparatorItem; - TTeamMenuItem* fPreviousDragTargetItem; + TTeamMenuItem* fPreviousDragTargetItem; TTeamMenuItem* fLastMousedOverItem; BMenuItem* fLastClickItem; diff --git a/src/apps/deskbar/InlineScrollView.cpp b/src/apps/deskbar/InlineScrollView.cpp new file mode 100644 index 0000000000..5d38f40797 --- /dev/null +++ b/src/apps/deskbar/InlineScrollView.cpp @@ -0,0 +1,622 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marc Flerackers (mflerackers@androme.be) + * Stefano Ceccherini (stefano.ceccherini@gmail.com) + * John Scipione (jscipione@gmail.com) + */ + + +#include "InlineScrollView.h" + +#include +#include +#include +#include +#include +#include +#include + + +const int kDefaultScrollStep = 19; +const int kScrollerDimension = 12; + + +class ScrollArrow : public BView { +public: + ScrollArrow(BRect frame); + virtual ~ScrollArrow(); + + bool IsEnabled() const { return fEnabled; }; + void SetEnabled(bool enabled); + +private: + bool fEnabled; +}; + + +class UpScrollArrow : public ScrollArrow { +public: + UpScrollArrow(BRect frame); + virtual ~UpScrollArrow(); + + virtual void Draw(BRect updateRect); + virtual void MouseDown(BPoint where); +}; + + +class DownScrollArrow : public ScrollArrow { +public: + DownScrollArrow(BRect frame); + virtual ~DownScrollArrow(); + + virtual void Draw(BRect updateRect); + virtual void MouseDown(BPoint where); +}; + + +class LeftScrollArrow : public ScrollArrow { +public: + LeftScrollArrow(BRect frame); + virtual ~LeftScrollArrow(); + + virtual void Draw(BRect updateRect); + virtual void MouseDown(BPoint where); +}; + + +class RightScrollArrow : public ScrollArrow { +public: + RightScrollArrow(BRect frame); + virtual ~RightScrollArrow(); + + virtual void Draw(BRect updateRect); + virtual void MouseDown(BPoint where); +}; + + +// #pragma mark - + + +ScrollArrow::ScrollArrow(BRect frame) + : + BView(frame, "menu scroll arrow", B_FOLLOW_NONE, B_WILL_DRAW), + fEnabled(false) +{ + SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); +} + + +ScrollArrow::~ScrollArrow() +{ +} + + +void +ScrollArrow::SetEnabled(bool enabled) +{ + fEnabled = enabled; + Invalidate(); +} + + +// #pragma mark - + + +UpScrollArrow::UpScrollArrow(BRect frame) + : + ScrollArrow(frame) +{ +} + + +UpScrollArrow::~UpScrollArrow() +{ +} + + +void +UpScrollArrow::Draw(BRect updateRect) +{ + SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), + B_DARKEN_1_TINT)); + + if (IsEnabled()) + SetHighColor(0, 0, 0); + else { + SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), + B_DARKEN_2_TINT)); + } + + FillRect(Bounds(), B_SOLID_LOW); + + float middle = Bounds().right / 2; + FillTriangle(BPoint(middle, (kScrollerDimension / 2) - 3), + BPoint(middle + 5, (kScrollerDimension / 2) + 2), + BPoint(middle - 5, (kScrollerDimension / 2) + 2)); +} + + +void +UpScrollArrow::MouseDown(BPoint where) +{ + if (!IsEnabled()) + return; + + TInlineScrollView* parent = dynamic_cast(Parent()); + if (parent == NULL) + return; + + float smallStep; + float largeStep; + parent->GetSteps(&smallStep, &largeStep); + + BMessage* message = Window()->CurrentMessage(); + int32 modifiers = 0; + message->FindInt32("modifiers", &modifiers); + // pressing the option/command/control key scrolls faster + if ((modifiers & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY)) != 0) + parent->ScrollBy(-largeStep); + else + parent->ScrollBy(-smallStep); + + snooze(5000); +} + + +// #pragma mark - + + +DownScrollArrow::DownScrollArrow(BRect frame) + : + ScrollArrow(frame) +{ +} + + +DownScrollArrow::~DownScrollArrow() +{ +} + + +void +DownScrollArrow::Draw(BRect updateRect) +{ + SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), + B_DARKEN_1_TINT)); + + if (IsEnabled()) + SetHighColor(0, 0, 0); + else { + SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), + B_DARKEN_2_TINT)); + } + + BRect frame = Bounds(); + FillRect(frame, B_SOLID_LOW); + + float middle = Bounds().right / 2; + FillTriangle(BPoint(middle, frame.bottom - (kScrollerDimension / 2) + 3), + BPoint(middle + 5, frame.bottom - (kScrollerDimension / 2) - 2), + BPoint(middle - 5, frame.bottom - (kScrollerDimension / 2) - 2)); +} + + +void +DownScrollArrow::MouseDown(BPoint where) +{ + if (!IsEnabled()) + return; + + TInlineScrollView* grandparent + = dynamic_cast(Parent()->Parent()); + if (grandparent == NULL) + return; + + float smallStep; + float largeStep; + grandparent->GetSteps(&smallStep, &largeStep); + + BMessage* message = Window()->CurrentMessage(); + int32 modifiers = 0; + message->FindInt32("modifiers", &modifiers); + // pressing the option/command/control key scrolls faster + if ((modifiers & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY)) != 0) + grandparent->ScrollBy(largeStep); + else + grandparent->ScrollBy(smallStep); + + snooze(5000); +} + + +// #pragma mark - + + +LeftScrollArrow::LeftScrollArrow(BRect frame) + : + ScrollArrow(frame) +{ +} + + +LeftScrollArrow::~LeftScrollArrow() +{ +} + + +void +LeftScrollArrow::Draw(BRect updateRect) +{ + SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT)); + + if (IsEnabled()) + SetHighColor(0, 0, 0); + else { + SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), + B_DARKEN_2_TINT)); + } + + FillRect(Bounds(), B_SOLID_LOW); + + float middle = Bounds().bottom / 2; + FillTriangle(BPoint((kScrollerDimension / 2) - 3, middle), + BPoint((kScrollerDimension / 2) + 2, middle + 5), + BPoint((kScrollerDimension / 2) + 2, middle - 5)); +} + + +void +LeftScrollArrow::MouseDown(BPoint where) +{ + if (!IsEnabled()) + return; + + TInlineScrollView* parent = dynamic_cast(Parent()); + if (parent == NULL) + return; + + float smallStep; + float largeStep; + parent->GetSteps(&smallStep, &largeStep); + + BMessage* message = Window()->CurrentMessage(); + int32 modifiers = 0; + message->FindInt32("modifiers", &modifiers); + // pressing the option/command/control key scrolls faster + if ((modifiers & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY)) != 0) + parent->ScrollBy(-largeStep); + else + parent->ScrollBy(-smallStep); + + snooze(5000); +} + + +// #pragma mark - + + +RightScrollArrow::RightScrollArrow(BRect frame) + : + ScrollArrow(frame) +{ +} + + +RightScrollArrow::~RightScrollArrow() +{ +} + + +void +RightScrollArrow::Draw(BRect updateRect) +{ + SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT)); + + if (IsEnabled()) + SetHighColor(0, 0, 0); + else { + SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), + B_DARKEN_2_TINT)); + } + + BRect frame = Bounds(); + FillRect(frame, B_SOLID_LOW); + + float middle = Bounds().bottom / 2; + FillTriangle(BPoint(kScrollerDimension / 2 + 3, middle), + BPoint(kScrollerDimension / 2 - 2, middle + 5), + BPoint(kScrollerDimension / 2 - 2, middle - 5)); +} + + +void +RightScrollArrow::MouseDown(BPoint where) +{ + if (!IsEnabled()) + return; + + TInlineScrollView* grandparent + = dynamic_cast(Parent()->Parent()); + if (grandparent == NULL) + return; + + float smallStep; + float largeStep; + grandparent->GetSteps(&smallStep, &largeStep); + + BMessage* message = Window()->CurrentMessage(); + int32 modifiers = 0; + message->FindInt32("modifiers", &modifiers); + // pressing the option/command/control key scrolls faster + if ((modifiers & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY)) != 0) + grandparent->ScrollBy(largeStep); + else + grandparent->ScrollBy(smallStep); + + snooze(5000); +} + + +// #pragma mark - + + +TInlineScrollView::TInlineScrollView(BRect frame, BView* target, + enum orientation orientation) + : + BView(frame, "inline scroll view", B_FOLLOW_NONE, B_WILL_DRAW), + fTarget(target), + fBeginScrollArrow(NULL), + fEndScrollArrow(NULL), + fScrollStep(kDefaultScrollStep), + fScrollValue(0), + fScrollLimit(0), + fOrientation(orientation) +{ +} + + +TInlineScrollView::~TInlineScrollView() +{ + if (fBeginScrollArrow != NULL) { + fBeginScrollArrow->RemoveSelf(); + delete fBeginScrollArrow; + fBeginScrollArrow = NULL; + } + + if (fEndScrollArrow != NULL) { + fEndScrollArrow->RemoveSelf(); + delete fEndScrollArrow; + fEndScrollArrow = NULL; + } +} + + +void +TInlineScrollView::AttachedToWindow() +{ + BView::AttachedToWindow(); + + if (fTarget == NULL) + return; + + AddChild(fTarget); + fTarget->MoveTo(0, 0); +} + + +void +TInlineScrollView::DetachedFromWindow() +{ + BView::DetachedFromWindow(); + + if (fTarget != NULL) + fTarget->RemoveSelf(); + + if (fBeginScrollArrow != NULL) + fBeginScrollArrow->RemoveSelf(); + + if (fEndScrollArrow != NULL) + fEndScrollArrow->RemoveSelf(); +} + + +void +TInlineScrollView::Draw(BRect updateRect) +{ + BRect frame = Bounds(); + be_control_look->DrawButtonBackground(this, frame, updateRect, + ui_color(B_MENU_BACKGROUND_COLOR)); +} + + +// #pragma mark - + + +void +TInlineScrollView::AttachScrollers() +{ + if (fTarget == NULL) + return; + + BRect frame = Bounds(); + + if (HasScrollers()) { + if (fOrientation == B_VERTICAL) { + fScrollLimit = fTarget->Bounds().Height() + - (frame.Height() - 2 * kScrollerDimension); + } else { + fScrollLimit = fTarget->Bounds().Width() + - (frame.Width() - 2 * kScrollerDimension); + } + return; + } + + fTarget->MakeFocus(true); + + if (fOrientation == B_VERTICAL) { + if (fBeginScrollArrow == NULL) { + fBeginScrollArrow = new UpScrollArrow( + BRect(frame.left, frame.top, frame.right, + kScrollerDimension - 1)); + AddChild(fBeginScrollArrow); + } + + if (fEndScrollArrow == NULL) { + fEndScrollArrow = new DownScrollArrow( + BRect(0, frame.bottom - 2 * kScrollerDimension + 1, frame.right, + frame.bottom - kScrollerDimension)); + fTarget->AddChild(fEndScrollArrow); + } + + fTarget->MoveBy(0, kScrollerDimension); + + fScrollLimit = fTarget->Bounds().Height() + - (frame.Height() - 2 * kScrollerDimension); + } else { + if (fBeginScrollArrow == NULL) { + fBeginScrollArrow = new LeftScrollArrow( + BRect(frame.left, frame.top, + frame.left + kScrollerDimension - 1, frame.bottom)); + AddChild(fBeginScrollArrow); + } + + if (fEndScrollArrow == NULL) { + fEndScrollArrow = new RightScrollArrow( + BRect(frame.right - 2 * kScrollerDimension + 1, frame.top, + frame.right, frame.bottom)); + fTarget->AddChild(fEndScrollArrow); + } + + fTarget->MoveBy(kScrollerDimension, 0); + + fScrollLimit = fTarget->Bounds().Width() + - (frame.Width() - 2 * kScrollerDimension); + } + + fBeginScrollArrow->SetEnabled(false); + fEndScrollArrow->SetEnabled(true); + + fScrollValue = 0; +} + + +void +TInlineScrollView::DetachScrollers() +{ + if (!HasScrollers()) + return; + + if (fEndScrollArrow) { + fEndScrollArrow->RemoveSelf(); + delete fEndScrollArrow; + fEndScrollArrow = NULL; + } + + if (fBeginScrollArrow) { + fBeginScrollArrow->RemoveSelf(); + delete fBeginScrollArrow; + fBeginScrollArrow = NULL; + } + + if (fTarget) { + // We don't remember the position where the last scrolling + // ended, so scroll back to the beginning. + if (fOrientation == B_VERTICAL) + fTarget->MoveBy(0, -kScrollerDimension); + else + fTarget->MoveBy(-kScrollerDimension, 0); + + fTarget->ScrollTo(0, 0); + fScrollValue = 0; + } +} + + +bool +TInlineScrollView::HasScrollers() const +{ + return fTarget != NULL && fBeginScrollArrow != NULL + && fEndScrollArrow != NULL; +} + + +void +TInlineScrollView::SetSmallStep(float step) +{ + fScrollStep = step; +} + + +void +TInlineScrollView::GetSteps(float* _smallStep, float* _largeStep) const +{ + if (_smallStep != NULL) + *_smallStep = fScrollStep; + if (_largeStep != NULL) { + *_largeStep = fScrollStep * 3; + } +} + + +void +TInlineScrollView::ScrollBy(const float& step) +{ + if (!HasScrollers()) + return; + + if (step > 0) { + if (fScrollValue == 0) + fBeginScrollArrow->SetEnabled(true); + + if (fScrollValue + step >= fScrollLimit) { + // If we reached the limit, only scroll to the end + if (fOrientation == B_VERTICAL) { + fTarget->ScrollBy(0, fScrollLimit - fScrollValue); + fEndScrollArrow->MoveBy(0, fScrollLimit - fScrollValue); + } else { + fTarget->ScrollBy(fScrollLimit - fScrollValue, 0); + fEndScrollArrow->MoveBy(fScrollLimit - fScrollValue, 0); + } + fEndScrollArrow->SetEnabled(false); + fScrollValue = fScrollLimit; + } else { + if (fOrientation == B_VERTICAL) { + fTarget->ScrollBy(0, step); + fEndScrollArrow->MoveBy(0, step); + } else { + fTarget->ScrollBy(step, 0); + fEndScrollArrow->MoveBy(step, 0); + } + fScrollValue += step; + } + } else if (step < 0) { + if (fScrollValue == fScrollLimit) + fEndScrollArrow->SetEnabled(true); + + if (fScrollValue + step <= 0) { + if (fOrientation == B_VERTICAL) { + fTarget->ScrollBy(0, -fScrollValue); + fEndScrollArrow->MoveBy(0, -fScrollValue); + } else { + fTarget->ScrollBy(-fScrollValue, 0); + fEndScrollArrow->MoveBy(-fScrollValue, 0); + } + fBeginScrollArrow->SetEnabled(false); + fScrollValue = 0; + } else { + if (fOrientation == B_VERTICAL) { + fTarget->ScrollBy(0, step); + fEndScrollArrow->MoveBy(0, step); + } else { + fTarget->ScrollBy(step, 0); + fEndScrollArrow->MoveBy(step, 0); + } + fScrollValue += step; + } + } + + //fTarget->Invalidate(); +} diff --git a/src/apps/deskbar/InlineScrollView.h b/src/apps/deskbar/InlineScrollView.h new file mode 100644 index 0000000000..0a80cbead5 --- /dev/null +++ b/src/apps/deskbar/InlineScrollView.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marc Flerackers (mflerackers@androme.be) + * Stefano Ceccherini (stefano.ceccherini@gmail.com) + * John Scipione (jscipione@gmail.com) + */ +#ifndef INLINE_SCROLL_VIEW_H +#define INLINE_SCROLL_VIEW_H + + +#include + + +class BLayout; +class BPoint; +class ScrollArrow; + +class TInlineScrollView : public BView { +public: + TInlineScrollView(BRect frame, BView* target, + enum orientation orientation = B_VERTICAL); + virtual ~TInlineScrollView(); + + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + + virtual void Draw(BRect updateRect); + + void AttachScrollers(); + void DetachScrollers(); + bool HasScrollers() const; + + void SetSmallStep(float step); + void GetSteps(float* _smallStep, + float* _largeStep) const; + void ScrollBy(const float& step); + +private: + BView* fTarget; + ScrollArrow* fBeginScrollArrow; + ScrollArrow* fEndScrollArrow; + + float fScrollStep; + float fScrollValue; + float fScrollLimit; + + int32 fOrientation; +}; + + +#endif // INLINE_SCROLL_VIEW_H diff --git a/src/apps/deskbar/Jamfile b/src/apps/deskbar/Jamfile index 8fc34a1c55..5f9c38a58a 100644 --- a/src/apps/deskbar/Jamfile +++ b/src/apps/deskbar/Jamfile @@ -27,6 +27,7 @@ Application Deskbar : DeskbarMenu.cpp DeskbarUtils.cpp ExpandoMenuBar.cpp + InlineScrollView.cpp PreferencesWindow.cpp ShowHideMenuItem.cpp StatusView.cpp diff --git a/src/apps/deskbar/TeamMenuItem.cpp b/src/apps/deskbar/TeamMenuItem.cpp index 5b7900f244..1d33cf66a1 100644 --- a/src/apps/deskbar/TeamMenuItem.cpp +++ b/src/apps/deskbar/TeamMenuItem.cpp @@ -240,7 +240,7 @@ TTeamMenuItem::GetContentSize(float* width, float* height) if (fDrawLabel && iconBounds.Width() > 32) *height += fLabelAscent + fLabelDescent; } else { - *height = iconBounds.Height() - kVPad * 8; + *height = iconBounds.Height() + kVPad * 4; } } *height += 2; @@ -559,7 +559,7 @@ TTeamMenuItem::ToggleExpandState(bool resizeWindow) sub->SetExpanded(true, myindex + childIndex); if (resizeWindow) - parent->SizeWindow(); + parent->SizeWindow(-1); } } } else { @@ -581,7 +581,7 @@ TTeamMenuItem::ToggleExpandState(bool resizeWindow) sub->SetExpanded(false, 0); if (resizeWindow) - parent->SizeWindow(); + parent->SizeWindow(1); } } } diff --git a/src/apps/deskcalc/CalcApplication.cpp b/src/apps/deskcalc/CalcApplication.cpp index 2e32e6266d..9c6d4c0052 100644 --- a/src/apps/deskcalc/CalcApplication.cpp +++ b/src/apps/deskcalc/CalcApplication.cpp @@ -22,6 +22,7 @@ #include #include +#include "CalcView.h" #include "CalcWindow.h" @@ -29,8 +30,9 @@ #define B_TRANSLATION_CONTEXT "CalcApplication" -static const char* kSettingsFileName = "DeskCalc_settings"; -const char* kAppSig = "application/x-vnd.Haiku-DeskCalc"; +static const char* kSettingsFileName = "DeskCalc_settings"; +const char* kAppName = B_TRANSLATE_SYSTEM_NAME("DeskCalc"); +const char* kSignature = "application/x-vnd.Haiku-DeskCalc"; static const float kDefaultWindowWidth = 220.0; static const float kDefaultWindowHeight = 140.0; @@ -38,7 +40,7 @@ static const float kDefaultWindowHeight = 140.0; CalcApplication::CalcApplication() : - BApplication(kAppSig), + BApplication(kSignature), fCalcWindow(NULL) { } @@ -66,8 +68,7 @@ CalcApplication::ReadyToRun() void CalcApplication::AboutRequested() { - // TODO: implement me! - return BApplication::AboutRequested(); + fCalcWindow->View()->MessageReceived(new BMessage(B_ABOUT_REQUESTED)); } diff --git a/src/apps/deskcalc/CalcApplication.h b/src/apps/deskcalc/CalcApplication.h index d47f445cec..d66f4be406 100644 --- a/src/apps/deskcalc/CalcApplication.h +++ b/src/apps/deskcalc/CalcApplication.h @@ -15,7 +15,8 @@ #include -extern const char* kAppSig; +extern const char* kAppName; +extern const char* kSignature; class BFile; class CalcWindow; diff --git a/src/apps/deskcalc/CalcView.cpp b/src/apps/deskcalc/CalcView.cpp index 73e2d7925e..b2af685692 100644 --- a/src/apps/deskcalc/CalcView.cpp +++ b/src/apps/deskcalc/CalcView.cpp @@ -138,24 +138,10 @@ CalcView::CalcView(BRect frame, rgb_color rgbBaseColor, BMessage* settings) fAudioFeedbackItem(NULL), fOptions(new CalcOptions()) { - // create expression text view - fExpressionTextView = new ExpressionTextView(_ExpressionRect(), this); - AddChild(fExpressionTextView); - - // read data from archive - _LoadSettings(settings); - // tell the app server not to erase our b/g SetViewColor(B_TRANSPARENT_32_BIT); - // parse calculator description - _ParseCalcDesc(fKeypadDescription); - - // colorize based on base color. - _Colorize(); - - // Fetch the calc icon for compact view - _FetchAppIcon(fCalcIcon); + _Init(settings); } @@ -188,15 +174,7 @@ CalcView::CalcView(BMessage* archive) // Do not restore the follow mode, in shelfs, we never follow. SetResizingMode(B_FOLLOW_NONE); - // create expression text view - fExpressionTextView = new ExpressionTextView(_ExpressionRect(), this); - AddChild(fExpressionTextView); - - // read data from archive - _LoadSettings(archive); - - // Fetch the calc icon for compact view - _FetchAppIcon(fCalcIcon); + _Init(archive); } @@ -205,6 +183,10 @@ CalcView::~CalcView() delete fKeypad; delete fOptions; free(fKeypadDescription); + + // replicant deleted, destroy the about window + if (fAboutWindow != NULL) + fAboutWindow->Quit(); } @@ -288,7 +270,31 @@ CalcView::MessageReceived(BMessage* message) // (replicant) about box requested case B_ABOUT_REQUESTED: - AboutRequested(); + if (fAboutWindow == NULL) { + // create the about window + const char* extraCopyrights[] = { + "1997, 1998 R3 Software Ltd.", + NULL + }; + + const char* authors[] = { + "Stephan Aßmus", + "John Scipione", + "Timothy Wayper", + "Ingo Weinhold", + NULL + }; + + fAboutWindow = new BAboutWindow(kAppName, kSignature); + fAboutWindow->AddCopyright(2006, "Haiku, Inc.", + extraCopyrights); + fAboutWindow->AddAuthors(authors); + fAboutWindow->Show(); + } else if (fAboutWindow->IsHidden()) + fAboutWindow->Show(); + else + fAboutWindow->Activate(); + break; case MSG_UNFLASH_KEY: @@ -296,6 +302,7 @@ CalcView::MessageReceived(BMessage* message) int32 key; if (message->FindInt32("key", &key) == B_OK) _FlashKey(key, 0); + break; } @@ -709,21 +716,6 @@ CalcView::FrameResized(float width, float height) } -void -CalcView::AboutRequested() -{ - const char* authors[] = { - "Timothy Wayper", - "Stephan Aßmus", - "Ingo Weinhold", - NULL - }; - BAboutWindow about(B_TRANSLATE_SYSTEM_NAME("DeskCalc"), 2006, authors, - B_UTF8_COPYRIGHT "1997, 1998 R3 Software Ltd."); - about.Show(); -} - - status_t CalcView::Archive(BMessage* archive, bool deep) const { @@ -736,7 +728,7 @@ CalcView::Archive(BMessage* archive, bool deep) const // save app signature for replicant add-on loading if (ret == B_OK) - ret = archive->AddString("add_on", kAppSig); + ret = archive->AddString("add_on", kSignature); // save all the options if (ret == B_OK) @@ -817,73 +809,6 @@ CalcView::Paste(BMessage* message) } -status_t -CalcView::_LoadSettings(BMessage* archive) -{ - if (!archive) - return B_BAD_VALUE; - - // record calculator description - const char* calcDesc; - if (archive->FindString("calcDesc", &calcDesc) < B_OK) - calcDesc = kKeypadDescriptionBasic; - - // save calculator description for reference - free(fKeypadDescription); - fKeypadDescription = strdup(calcDesc); - - // read grid dimensions - if (archive->FindInt16("cols", &fColumns) < B_OK) - fColumns = 5; - if (archive->FindInt16("rows", &fRows) < B_OK) - fRows = 4; - - // read color scheme - const rgb_color* color; - ssize_t size; - if (archive->FindData("rgbBaseColor", B_RGB_COLOR_TYPE, - (const void**)&color, &size) < B_OK - || size != sizeof(rgb_color)) { - fBaseColor = ui_color(B_PANEL_BACKGROUND_COLOR); - puts("Missing rgbBaseColor from CalcView archive!\n"); - } else { - fBaseColor = *color; - } - - if (archive->FindData("rgbDisplay", B_RGB_COLOR_TYPE, - (const void**)&color, &size) < B_OK - || size != sizeof(rgb_color)) { - fExpressionBGColor = (rgb_color){ 0, 0, 0, 255 }; - puts("Missing rgbBaseColor from CalcView archive!\n"); - } else { - fExpressionBGColor = *color; - } - - // load options - fOptions->LoadSettings(archive); - - // load display text - const char* display; - if (archive->FindString("displayText", &display) < B_OK) { - puts("Missing expression text from CalcView archive.\n"); - } else { - // init expression text - fExpressionTextView->SetText(display); - } - - // load expression history - fExpressionTextView->LoadSettings(archive); - - // parse calculator description - _ParseCalcDesc(fKeypadDescription); - - // colorize based on base color. - _Colorize(); - - return B_OK; -} - - status_t CalcView::SaveSettings(BMessage* archive) const { @@ -1069,6 +994,90 @@ CalcView::SetKeypadMode(uint8 mode) // #pragma mark - +void +CalcView::_Init(BMessage* settings) +{ + // create expression text view + fExpressionTextView = new ExpressionTextView(_ExpressionRect(), this); + AddChild(fExpressionTextView); + + // read data from archive + _LoadSettings(settings); + + // fetch the calc icon for compact view + _FetchAppIcon(fCalcIcon); + + fAboutWindow = NULL; +} + + +status_t +CalcView::_LoadSettings(BMessage* archive) +{ + if (!archive) + return B_BAD_VALUE; + + // record calculator description + const char* calcDesc; + if (archive->FindString("calcDesc", &calcDesc) < B_OK) + calcDesc = kKeypadDescriptionBasic; + + // save calculator description for reference + free(fKeypadDescription); + fKeypadDescription = strdup(calcDesc); + + // read grid dimensions + if (archive->FindInt16("cols", &fColumns) < B_OK) + fColumns = 5; + if (archive->FindInt16("rows", &fRows) < B_OK) + fRows = 4; + + // read color scheme + const rgb_color* color; + ssize_t size; + if (archive->FindData("rgbBaseColor", B_RGB_COLOR_TYPE, + (const void**)&color, &size) < B_OK + || size != sizeof(rgb_color)) { + fBaseColor = ui_color(B_PANEL_BACKGROUND_COLOR); + puts("Missing rgbBaseColor from CalcView archive!\n"); + } else { + fBaseColor = *color; + } + + if (archive->FindData("rgbDisplay", B_RGB_COLOR_TYPE, + (const void**)&color, &size) < B_OK + || size != sizeof(rgb_color)) { + fExpressionBGColor = (rgb_color){ 0, 0, 0, 255 }; + puts("Missing rgbBaseColor from CalcView archive!\n"); + } else { + fExpressionBGColor = *color; + } + + // load options + fOptions->LoadSettings(archive); + + // load display text + const char* display; + if (archive->FindString("displayText", &display) < B_OK) { + puts("Missing expression text from CalcView archive.\n"); + } else { + // init expression text + fExpressionTextView->SetText(display); + } + + // load expression history + fExpressionTextView->LoadSettings(archive); + + // parse calculator description + _ParseCalcDesc(fKeypadDescription); + + // colorize based on base color. + _Colorize(); + + return B_OK; +} + + void CalcView::_ParseCalcDesc(const char* keypadDescription) { @@ -1368,7 +1377,7 @@ void CalcView::_FetchAppIcon(BBitmap* into) { entry_ref appRef; - status_t status = be_roster->FindApp(kAppSig, &appRef); + status_t status = be_roster->FindApp(kSignature, &appRef); if (status == B_OK) { BFile file(&appRef, B_READ_ONLY); BAppFileInfo appInfo(&file); diff --git a/src/apps/deskcalc/CalcView.h b/src/apps/deskcalc/CalcView.h index c004f668fb..446d44dfd9 100644 --- a/src/apps/deskcalc/CalcView.h +++ b/src/apps/deskcalc/CalcView.h @@ -31,8 +31,10 @@ static const float kMaximumWidthBasic = 400.0f; static const float kMinimumHeightBasic = 130.0f; static const float kMaximumHeightBasic = 400.0f; +class BAboutWindow; class BString; class BMenuItem; +class BMessage; class BPopUpMenu; class CalcOptions; class CalcOptionsWindow; @@ -48,9 +50,7 @@ class CalcView : public BView { CalcView(BRect frame, rgb_color rgbBaseColor, BMessage* settings); - CalcView(BMessage* archive); - virtual ~CalcView(); virtual void AttachedToWindow(); @@ -60,12 +60,9 @@ class CalcView : public BView { virtual void MouseUp(BPoint point); virtual void KeyDown(const char* bytes, int32 numBytes); virtual void MakeFocus(bool focused = true); - virtual void ResizeTo(float width, float height); + virtual void ResizeTo(float width, float height); virtual void FrameResized(float width, float height); - // Present about box for view (replicant). - virtual void AboutRequested(); - // Archive this view. virtual status_t Archive(BMessage* archive, bool deep) const; @@ -101,6 +98,8 @@ class CalcView : public BView { void SetKeypadMode(uint8 mode); private: + void _Init(BMessage* settings); + status_t _LoadSettings(BMessage* archive); void _ParseCalcDesc(const char* keypadDescription); void _PressKey(int key); @@ -120,8 +119,6 @@ class CalcView : public BView { void _FetchAppIcon(BBitmap* into); - status_t _LoadSettings(BMessage* archive); - // grid dimensions int16 fColumns; int16 fRows; @@ -164,6 +161,9 @@ class CalcView : public BView { // calculator options. CalcOptions* fOptions; + + // about window for replicant + BAboutWindow* fAboutWindow; }; #endif // _CALC_VIEW_H diff --git a/src/apps/deskcalc/CalcWindow.cpp b/src/apps/deskcalc/CalcWindow.cpp index 4a3740edb3..ae6e337c42 100644 --- a/src/apps/deskcalc/CalcWindow.cpp +++ b/src/apps/deskcalc/CalcWindow.cpp @@ -21,6 +21,7 @@ #include #include +#include "CalcApplication.h" #include "CalcOptions.h" #include "CalcView.h" @@ -31,8 +32,8 @@ CalcWindow::CalcWindow(BRect frame, BMessage* settings) : - BWindow(frame, B_TRANSLATE_SYSTEM_NAME("DeskCalc"), B_TITLED_WINDOW, - B_ASYNCHRONOUS_CONTROLS | B_NOT_ANCHORED_ON_ACTIVATE) + BWindow(frame, kAppName, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS + | B_NOT_ANCHORED_ON_ACTIVATE) { // create calculator view with calculator description and // desktop background color diff --git a/src/apps/deskcalc/CalcWindow.h b/src/apps/deskcalc/CalcWindow.h index 421f4605a9..5e6b16c769 100644 --- a/src/apps/deskcalc/CalcWindow.h +++ b/src/apps/deskcalc/CalcWindow.h @@ -31,6 +31,8 @@ class CalcWindow : public BWindow { void SetFrame(BRect frame, bool forceCenter = false); + CalcView* View() const { return fCalcView; }; + private: CalcView* fCalcView; }; diff --git a/src/apps/deskcalc/DeskCalc.rdef b/src/apps/deskcalc/DeskCalc.rdef index eb159ece92..73cd064257 100644 --- a/src/apps/deskcalc/DeskCalc.rdef +++ b/src/apps/deskcalc/DeskCalc.rdef @@ -5,14 +5,14 @@ resource app_name_catalog_entry "x-vnd.Haiku-DeskCalc:System name:DeskCalc"; resource app_version { major = 2, - middle = 2, + middle = 4, minor = 0, - variety = B_APPV_ALPHA, + variety = B_APPV_FINAL, internal = 1, short_info = "DeskCalc", - long_info = "DeskCalc ©2006-2012 Haiku, Inc." + long_info = "DeskCalc ©1997, 1998 R3 Software Ltd. ©2006-2012 Haiku, Inc." }; resource app_flags B_SINGLE_LAUNCH; @@ -31,4 +31,3 @@ resource vector_icon { $"011001178400040A010102000A050105000A06030806071001178122040A0201" $"03000A030104000A0706090A0B0D0E0C100117810004" }; - diff --git a/src/apps/networkstatus/Jamfile b/src/apps/networkstatus/Jamfile index 9cc32fba80..c05d505124 100644 --- a/src/apps/networkstatus/Jamfile +++ b/src/apps/networkstatus/Jamfile @@ -17,7 +17,7 @@ Application NetworkStatus : RadioView.cpp WirelessNetworkMenuItem.cpp - : be $(HAIKU_LOCALE_LIBS) $(icon_libs) $(TARGET_NETWORK_LIBS) + : be libshared.a $(HAIKU_LOCALE_LIBS) $(icon_libs) $(TARGET_NETWORK_LIBS) libbnetapi.so $(TARGET_LIBSTDC++) : NetworkStatus.rdef NetworkStatusIcons.rdef ; diff --git a/src/apps/networkstatus/NetworkStatusView.cpp b/src/apps/networkstatus/NetworkStatusView.cpp index 626cb60757..ccbdb85b9a 100644 --- a/src/apps/networkstatus/NetworkStatusView.cpp +++ b/src/apps/networkstatus/NetworkStatusView.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -138,12 +139,16 @@ NetworkStatusView::NetworkStatusView(BMessage* archive) NetworkStatusView::~NetworkStatusView() { + if (fAboutWindow != NULL) + fAboutWindow->Quit(); } void NetworkStatusView::_Init() { + fAboutWindow = NULL; + for (int i = 0; i < kStatusCount; i++) { fTrayIcons[i] = NULL; fNotifyIcons[i] = NULL; @@ -216,7 +221,7 @@ NetworkStatusView::_Quit() } -NetworkStatusView * +NetworkStatusView* NetworkStatusView::Instantiate(BMessage* archive) { if (!validate_instantiation(archive, "NetworkStatusView")) @@ -503,26 +508,22 @@ NetworkStatusView::MouseDown(BPoint point) void NetworkStatusView::_AboutRequested() { - BString about = B_TRANSLATE( - "NetworkStatus\n\twritten by %1 and Hugo Santos\n\t%2, Haiku, Inc.\n" - ); - about.ReplaceFirst("%1", "Axel Dörfler"); - // Append a new developer here - about.ReplaceFirst("%2", "Copyright 2007-2010"); - // Append a new year here - BAlert* alert = new BAlert("about", about, B_TRANSLATE("OK")); - alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); - BTextView *view = alert->TextView(); - BFont font; + if (fAboutWindow == NULL) { + const char* authors[] = { + "Axel Dörfler", + "Hugo Santos", + NULL + }; - view->SetStylable(true); - - view->GetFont(&font); - font.SetSize(18); - font.SetFace(B_BOLD_FACE); - view->SetFontAndColor(0, 13, &font); - - alert->Go(); + fAboutWindow = new BAboutWindow( + B_TRANSLATE_SYSTEM_NAME("NetworkStatus"), kSignature); + fAboutWindow->AddCopyright(2007, "Haiku, Inc."); + fAboutWindow->AddAuthors(authors); + fAboutWindow->Show(); + } else if (fAboutWindow->IsHidden()) + fAboutWindow->Show(); + else + fAboutWindow->Activate(); } diff --git a/src/apps/networkstatus/NetworkStatusView.h b/src/apps/networkstatus/NetworkStatusView.h index 8508efe6cc..53e6b3ab37 100644 --- a/src/apps/networkstatus/NetworkStatusView.h +++ b/src/apps/networkstatus/NetworkStatusView.h @@ -16,6 +16,8 @@ #include + +class BAboutWindow; class BMessageRunner; class BNetworkInterface; @@ -64,6 +66,7 @@ class NetworkStatusView : public BView { std::map fInterfaceStatuses; + BAboutWindow* fAboutWindow; bool fInDeskbar; BBitmap* fTrayIcons[kStatusCount]; BBitmap* fNotifyIcons[kStatusCount]; diff --git a/src/apps/powerstatus/Jamfile b/src/apps/powerstatus/Jamfile index 6ce508e3ab..59d8d7a82d 100644 --- a/src/apps/powerstatus/Jamfile +++ b/src/apps/powerstatus/Jamfile @@ -13,7 +13,7 @@ Application PowerStatus : PowerStatusWindow.cpp PowerStatusView.cpp PowerStatus.cpp - : be $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) + : be libshared.a $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) : PowerStatus.rdef ; DoCatalogs PowerStatus : diff --git a/src/apps/powerstatus/PowerStatusView.cpp b/src/apps/powerstatus/PowerStatusView.cpp index 0d540f60cc..1fced11ca3 100644 --- a/src/apps/powerstatus/PowerStatusView.cpp +++ b/src/apps/powerstatus/PowerStatusView.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include @@ -77,6 +77,8 @@ PowerStatusView::PowerStatusView(BMessage* archive) PowerStatusView::~PowerStatusView() { + if (fAboutWindow != NULL) + fAboutWindow->Quit(); } @@ -96,6 +98,8 @@ PowerStatusView::_Init() { SetViewColor(B_TRANSPARENT_COLOR); + fAboutWindow = NULL; + fShowLabel = true; fShowTime = false; fShowStatusIcon = true; @@ -503,14 +507,16 @@ PowerStatusReplicant::PowerStatusReplicant(BMessage* archive) PowerStatusReplicant::~PowerStatusReplicant() { - if (fMessengerExist) { + if (fMessengerExist) delete fExtWindowMessenger; - } fDriverInterface->StopWatching(this); fDriverInterface->Disconnect(); fDriverInterface->ReleaseReference(); + if (fAboutWindow != NULL) + fAboutWindow->Quit(); + _SaveSettings(); } @@ -621,22 +627,23 @@ PowerStatusReplicant::MouseDown(BPoint point) void PowerStatusReplicant::_AboutRequested() { - BAlert* alert = new BAlert(B_TRANSLATE("About"), - B_TRANSLATE("PowerStatus\n" - "written by Axel Dörfler, Clemens Zeidler\n" - "Copyright 2006, Haiku, Inc.\n"), B_TRANSLATE("OK")); - BTextView *view = alert->TextView(); - BFont font; + if (fAboutWindow == NULL) { + const char* authors[] = { + "Axel Dörfler", + "Alexander von Gluck", + "Clemens Zeidler", + NULL + }; - view->SetStylable(true); - - view->GetFont(&font); - font.SetSize(18); - font.SetFace(B_BOLD_FACE); - view->SetFontAndColor(0, strlen(B_TRANSLATE("PowerStatus")), &font); - - alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); - alert->Go(); + fAboutWindow = new BAboutWindow( + B_TRANSLATE_SYSTEM_NAME("PowerStatus"), kSignature); + fAboutWindow->AddCopyright(2006, "Haiku, Inc."); + fAboutWindow->AddAuthors(authors); + fAboutWindow->Show(); + } else if (fAboutWindow->IsHidden()) + fAboutWindow->Show(); + else + fAboutWindow->Activate(); } diff --git a/src/apps/powerstatus/PowerStatusView.h b/src/apps/powerstatus/PowerStatusView.h index 837bb2d3e1..6661b47504 100644 --- a/src/apps/powerstatus/PowerStatusView.h +++ b/src/apps/powerstatus/PowerStatusView.h @@ -15,6 +15,7 @@ #include "DriverInterface.h" +class BAboutWindow; class BFile; @@ -53,6 +54,7 @@ private: protected: PowerStatusDriverInterface* fDriverInterface; + BAboutWindow* fAboutWindow; bool fShowLabel; bool fShowTime; diff --git a/src/apps/processcontroller/ProcessController.cpp b/src/apps/processcontroller/ProcessController.cpp index 8f9417554c..28e708db40 100644 --- a/src/apps/processcontroller/ProcessController.cpp +++ b/src/apps/processcontroller/ProcessController.cpp @@ -1,7 +1,7 @@ /* ProcessController © 2000, Georges-Edouard Berenger, All Rights Reserved. Copyright (C) 2004 beunited.org - Copyright (c) 2006-2009, Haiku, Inc. All rights reserved. + Copyright (c) 2006-2012, Haiku, Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -204,6 +204,10 @@ ProcessController::~ProcessController() delete fMessageRunner; gPCView = NULL; + + // replicant deleted, destroy the about window + if (fAboutWindow != NULL) + fAboutWindow->Quit(); } @@ -217,10 +221,11 @@ ProcessController::Init() memset(fCPUTimes, 0, sizeof(fCPUTimes)); memset(fPrevActive, 0, sizeof(fPrevActive)); fPrevTime = 0; + fAboutWindow = NULL; } -ProcessController * +ProcessController* ProcessController::Instantiate(BMessage *data) { if (!validate_instantiation(data, kClassName)) @@ -433,15 +438,27 @@ ProcessController::MessageReceived(BMessage *message) void ProcessController::AboutRequested() { - const char* authors[] = { - "Georges-Edouard Berenger", - NULL - }; + if (fAboutWindow == NULL) { + const char* extraCopyrights[] = { + "2004 beunited.org", + "1997-2001 Georges-Edouard Berenger", + NULL + }; - BAboutWindow about(B_TRANSLATE_SYSTEM_NAME("ProcessController"), 2007, authors, - "Copyright 1997-2001\n" - "Georges-Edouard Berenger."); - about.Show(); + const char* authors[] = { + "Georges-Edouard Berenger", + NULL + }; + + fAboutWindow = new BAboutWindow( + B_TRANSLATE_SYSTEM_NAME("ProcessController"), kSignature); + fAboutWindow->AddCopyright(2007, "Haiku, Inc.", extraCopyrights); + fAboutWindow->AddAuthors(authors); + fAboutWindow->Show(); + } else if (fAboutWindow->IsHidden()) + fAboutWindow->Show(); + else + fAboutWindow->Activate(); } diff --git a/src/apps/processcontroller/ProcessController.h b/src/apps/processcontroller/ProcessController.h index d158c6b8cb..78d1212741 100644 --- a/src/apps/processcontroller/ProcessController.h +++ b/src/apps/processcontroller/ProcessController.h @@ -1,6 +1,7 @@ /* ProcessController © 2000, Georges-Edouard Berenger, All Rights Reserved. - Copyright (C) 2004 beunited.org + Copyright (C) 2004 beunited.org + Copyright (c) 2006-2012, Haiku, Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,6 +26,7 @@ #include +class BAboutWindow; class BMessageRunner; class ThreadBarMenu; @@ -58,6 +60,7 @@ class ProcessController : public BView { private: void Init(); + BAboutWindow* fAboutWindow; bool fTemp; float fMemoryUsage; float fLastBarHeight[B_MAX_CPU_COUNT]; diff --git a/src/apps/workspaces/Jamfile b/src/apps/workspaces/Jamfile index e9fbe094b1..cdc936ac87 100644 --- a/src/apps/workspaces/Jamfile +++ b/src/apps/workspaces/Jamfile @@ -3,11 +3,11 @@ SubDir HAIKU_TOP src apps workspaces ; SetSubDirSupportedPlatformsBeOSCompatible ; AddSubDirSupportedPlatforms libbe_test ; -UsePrivateHeaders app interface ; +UsePrivateHeaders app interface shared ; Application Workspaces : Workspaces.cpp - : be $(HAIKU_LOCALE_LIBS) $(TARGET_LIBSUPC++) + : be libshared.a $(HAIKU_LOCALE_LIBS) $(TARGET_LIBSUPC++) : Workspaces.rdef ; diff --git a/src/apps/workspaces/Workspaces.cpp b/src/apps/workspaces/Workspaces.cpp index 0c3ea0fc75..f5d5de5467 100644 --- a/src/apps/workspaces/Workspaces.cpp +++ b/src/apps/workspaces/Workspaces.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009, Haiku, Inc. All rights reserved. + * Copyright 2002-2012, Haiku, Inc. All rights reserved. * Copyright 2002, François Revol, revol@free.fr. * This file is distributed under the terms of the MIT License. * @@ -11,7 +11,7 @@ */ -#include +#include #include #include #include @@ -119,6 +119,7 @@ class WorkspacesView : public BView { BView* fParentWhichDrawsOnChildren; BRect fCurrentFrame; + BAboutWindow* fAboutWindow; }; class WorkspacesWindow : public BWindow { @@ -341,7 +342,8 @@ WorkspacesView::WorkspacesView(BRect frame, bool showDragger=true) BView(frame, kDeskbarItemName, B_FOLLOW_ALL, kWorkspacesViewFlag | B_FRAME_EVENTS), fParentWhichDrawsOnChildren(NULL), - fCurrentFrame(frame) + fCurrentFrame(frame), + fAboutWindow(NULL) { if(showDragger) { frame.OffsetTo(B_ORIGIN); @@ -358,7 +360,8 @@ WorkspacesView::WorkspacesView(BMessage* archive) : BView(archive), fParentWhichDrawsOnChildren(NULL), - fCurrentFrame(Frame()) + fCurrentFrame(Frame()), + fAboutWindow(NULL) { // Just in case we are instantiated from an older archive... SetFlags(Flags() | B_FRAME_EVENTS); @@ -371,6 +374,8 @@ WorkspacesView::WorkspacesView(BMessage* archive) WorkspacesView::~WorkspacesView() { + if (fAboutWindow != NULL) + fAboutWindow->Quit(); } @@ -400,28 +405,34 @@ WorkspacesView::Archive(BMessage* archive, bool deep) const void WorkspacesView::_AboutRequested() { - BString text = B_TRANSLATE("Workspaces\n" - "written by %1, and %2.\n\n" - "Copyright %3, Haiku.\n\n" - "Send windows behind using the Option key. " - "Move windows to front using the Control key.\n"); - text.ReplaceFirst("%1", "François Revol, Axel Dörfler"); - text.ReplaceFirst("%2", "Matt Madia"); - text.ReplaceFirst("%3", "2002-2008"); - - BAlert *alert = new BAlert("about", text.String(), B_TRANSLATE("OK")); - BTextView *view = alert->TextView(); - BFont font; + if (fAboutWindow == NULL) { + const char* authors[] = { + "Axel Dörfler", + "Oliver \"Madison\" Kohl", + "Matt Madia", + "François Revol", + NULL + }; - view->SetStylable(true); + const char* extraCopyrights[] = { + "2002 François Revol", + NULL + }; - view->GetFont(&font); - font.SetSize(18); - font.SetFace(B_BOLD_FACE); - view->SetFontAndColor(0, 10, &font); + const char* extraInfo = "Send windows behind using the Option key. " + "Move windows to front using the Control key.\n"; - alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); - alert->Go(); + fAboutWindow = new BAboutWindow( + B_TRANSLATE_SYSTEM_NAME("Workspaces"), kSignature); + fAboutWindow->AddCopyright(2002, "Haiku, Inc.", + extraCopyrights); + fAboutWindow->AddAuthors(authors); + fAboutWindow->AddExtraInfo(extraInfo); + fAboutWindow->Show(); + } else if (fAboutWindow->IsHidden()) + fAboutWindow->Show(); + else + fAboutWindow->Activate(); } diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp index 09bf7e4d91..36db0779ad 100644 --- a/src/kits/app/Message.cpp +++ b/src/kits/app/Message.cpp @@ -2564,6 +2564,7 @@ DEFINE_SET_GET_FUNCTIONS(uint64, UInt64, B_UINT64_TYPE); DEFINE_SET_GET_FUNCTIONS(bool, Bool, B_BOOL_TYPE); DEFINE_SET_GET_FUNCTIONS(float, Float, B_FLOAT_TYPE); DEFINE_SET_GET_FUNCTIONS(double, Double, B_DOUBLE_TYPE); +DEFINE_SET_GET_FUNCTIONS(const char *, String, B_STRING_TYPE); #undef DEFINE_SET_GET_FUNCTION @@ -3135,6 +3136,13 @@ BMessage::HasFlat(const char *name, int32 index, const BFlattenable *object) } +status_t +BMessage::SetString(const char *name, const BString& value) +{ + return SetData(name, B_STRING_TYPE, value.String(), value.Length() + 1); +} + + status_t BMessage::SetData(const char* name, type_code type, const void* data, ssize_t numBytes) diff --git a/src/kits/shared/AboutWindow.cpp b/src/kits/shared/AboutWindow.cpp index e8fbe72bf0..8e4d103d89 100644 --- a/src/kits/shared/AboutWindow.cpp +++ b/src/kits/shared/AboutWindow.cpp @@ -1,39 +1,348 @@ /* - * Copyright 2007-2009 Haiku, Inc. + * Copyright 2007-2012 Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: - * Ryan Leavengood, leavengood@gmail.com + * Ryan Leavengood + * John Scipione */ + #include #include #include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include +#include +#include + + +static const float kStripeWidth = 30.0; using BPrivate::gSystemCatalog; - #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "AboutWindow" -BAboutWindow::BAboutWindow(const char *appName, int32 firstCopyrightYear, - const char **authors, const char *extraInfo) -{ - fAppName = new BString(appName); +class StripeView : public BView { + public: + StripeView(BBitmap* icon); + virtual ~StripeView(); - const char* copyright = gSystemCatalog.GetString( - B_TRANSLATE_MARK("Copyright " B_UTF8_COPYRIGHT " %years% Haiku, Inc."), - "AboutWindow"); - const char* writtenBy = gSystemCatalog.GetString( - B_TRANSLATE_MARK("Written by:"), "AboutWindow"); + virtual void Draw(BRect updateRect); + + private: + BBitmap* fIcon; +}; + + +class AboutView : public BGroupView { + public: + AboutView(const char* name, + const char* signature); + virtual ~AboutView(); + + BTextView* InfoView() const { return fInfoView; }; + + protected: + const char* AppVersion(const char* signature); + BBitmap* AppIcon(const char* signature); + + private: + BStringView* fNameView; + BStringView* fVersionView; + BTextView* fInfoView; +}; + + +// #pragma mark - + + +StripeView::StripeView(BBitmap* icon) + : + BView("StripeView", B_WILL_DRAW), + fIcon(icon) +{ + float width = 0.0f; + if (icon != NULL) + width += icon->Bounds().Width() + 32.0f; + + SetExplicitMinSize(BSize(width, B_SIZE_UNSET)); + SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED)); + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); +} + + +StripeView::~StripeView() +{ +} + + +void +StripeView::Draw(BRect updateRect) +{ + if (fIcon == NULL) + return; + + SetHighColor(ViewColor()); + FillRect(updateRect); + + BRect stripeRect = Bounds(); + stripeRect.right = kStripeWidth; + SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); + FillRect(stripeRect); + + SetDrawingMode(B_OP_ALPHA); + SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); + DrawBitmapAsync(fIcon, BPoint(15.0f, 10.0f)); +} + + +// #pragma mark - + + +AboutView::AboutView(const char* appName, const char* signature) + : + BGroupView("AboutView", B_VERTICAL) +{ + fNameView = new BStringView("name", appName); + BFont font; + fNameView->GetFont(&font); + font.SetFace(B_BOLD_FACE); + font.SetSize(font.Size() * 2.0); + fNameView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE + | B_FONT_FLAGS); + + fVersionView = new BStringView("version", AppVersion(signature)); + + fInfoView = new BTextView("info", B_WILL_DRAW); + fInfoView->SetExplicitMinSize(BSize(210.0, 160.0)); + fInfoView->MakeEditable(false); + fInfoView->SetWordWrap(true); + fInfoView->SetInsets(5.0, 5.0, 5.0, 5.0); + fInfoView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + fInfoView->SetHighColor(ui_color(B_DOCUMENT_TEXT_COLOR)); + + BScrollView* infoViewScroller = new BScrollView( + "infoViewScroller", fInfoView, B_WILL_DRAW | B_FRAME_EVENTS, + false, true, B_PLAIN_BORDER); + + GroupLayout()->SetSpacing(0); + BLayoutBuilder::Group<>(this) + .AddGroup(B_HORIZONTAL, 0) + .Add(new StripeView(AppIcon(signature))) + .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING) + .SetInsets(0, B_USE_DEFAULT_SPACING, + B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) + .Add(fNameView) + .Add(fVersionView) + .Add(infoViewScroller) + .End() + .AddGlue() + .End(); +} + + +AboutView::~AboutView() +{ +} + + +const char* +AboutView::AppVersion(const char* signature) +{ + if (signature == NULL) + return NULL; + + entry_ref ref; + if (be_roster->FindApp(signature, &ref) != B_OK) + return NULL; + + BFile file(&ref, B_READ_ONLY); + BAppFileInfo appMime(&file); + if (appMime.InitCheck() != B_OK) + return NULL; + + version_info versionInfo; + if (appMime.GetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK) { + if (versionInfo.major == 0 && versionInfo.middle == 0 + && versionInfo.minor == 0) { + return NULL; + } + + const char* version = B_TRANSLATE_MARK("Version"); + version = gSystemCatalog.GetString(version, "AboutWindow"); + BString appVersion(version); + appVersion << " " << versionInfo.major << "." << versionInfo.middle; + if (versionInfo.minor > 0) + appVersion << "." << versionInfo.minor; + + // Add the version variety + const char* variety = NULL; + switch (versionInfo.variety) { + case B_DEVELOPMENT_VERSION: + variety = B_TRANSLATE_MARK("development"); + break; + case B_ALPHA_VERSION: + variety = B_TRANSLATE_MARK("alpha"); + break; + case B_BETA_VERSION: + variety = B_TRANSLATE_MARK("beta"); + break; + case B_GAMMA_VERSION: + variety = B_TRANSLATE_MARK("gamma"); + break; + case B_GOLDEN_MASTER_VERSION: + variety = B_TRANSLATE_MARK("gold master"); + break; + } + + if (variety != NULL) { + variety = gSystemCatalog.GetString(variety, "AboutWindow"); + appVersion << "-" << variety; + } + + return appVersion.String(); + } + + return NULL; +} + + +BBitmap* +AboutView::AppIcon(const char* signature) +{ + if (signature == NULL) + return NULL; + + entry_ref ref; + if (be_roster->FindApp(signature, &ref) != B_OK) + return NULL; + + BFile file(&ref, B_READ_ONLY); + BAppFileInfo appMime(&file); + if (appMime.InitCheck() != B_OK) + return NULL; + + BBitmap* icon = new BBitmap(BRect(0.0, 0.0, 127.0, 127.0), B_RGBA32); + if (appMime.GetIcon(icon, (icon_size)128) == B_OK) + return icon; + + delete icon; + return NULL; +} + + +// #pragma mark - + + +BAboutWindow::BAboutWindow(const char* appName, const char* signature) + : BWindow(BRect(0.0, 0.0, 200.0, 200.0), appName, B_TITLED_WINDOW, + B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE + | B_AUTO_UPDATE_SIZE_LIMITS) +{ + SetLayout(new BGroupLayout(B_VERTICAL)); + + const char* about = B_TRANSLATE_MARK("About"); + about = gSystemCatalog.GetString(about, "AboutWindow"); + + BString title(about); + title << " " << appName; + SetTitle(title.String()); + + fAboutView = new AboutView(appName, signature); + AddChild(fAboutView); + + MoveTo(AboutPosition(Frame().Width(), Frame().Height())); +} + + +BAboutWindow::~BAboutWindow() +{ + fAboutView->RemoveSelf(); + delete fAboutView; + fAboutView = NULL; +} + + +bool +BAboutWindow::QuitRequested() +{ + Hide(); + + return false; +} + + +// #pragma mark - + + +BPoint +BAboutWindow::AboutPosition(float width, float height) +{ + BPoint result(100, 100); + + BWindow* window = + dynamic_cast(BLooper::LooperForThread(find_thread(NULL))); + + BScreen screen(window); + BRect screenFrame(0, 0, 640, 480); + if (screen.IsValid()) + screenFrame = screen.Frame(); + + // Horizontally, we're smack in the middle + result.x = screenFrame.left + (screenFrame.Width() / 2.0) - (width / 2.0); + + // This is probably sooo wrong, but it looks right on 1024 x 768 + result.y = screenFrame.top + (screenFrame.Height() / 4.0) + - ceil(height / 3.0); + + return result; +} + + +void +BAboutWindow::AddDescription(const char* description) +{ + if (description == NULL) + return; + + const char* appDesc = B_TRANSLATE_MARK(description); + appDesc = gSystemCatalog.GetString(appDesc, "AboutWindow"); + + BString desc(""); + if (fAboutView->InfoView()->TextLength() > 0) + desc << "\n\n"; + + desc << appDesc; + + fAboutView->InfoView()->Insert(desc.String()); +} + + +void +BAboutWindow::AddCopyright(int32 firstCopyrightYear, + const char* copyrightHolder, const char** extraCopyrights) +{ + BString copyright(B_UTF8_COPYRIGHT " %years% %holder%"); // Get current year time_t tp; @@ -45,50 +354,112 @@ BAboutWindow::BAboutWindow(const char *appName, int32 firstCopyrightYear, if (copyrightYears != currentYear) copyrightYears << "-" << currentYear; - // Build the text to display - BString text(appName); - text << "\n\n"; + BString text(""); + if (fAboutView->InfoView()->TextLength() > 0) + text << "\n\n"; + text << copyright; - text << "\n\n"; + + // Fill out the copyright year placeholder text.ReplaceAll("%years%", copyrightYears.String()); - text << writtenBy << "\n"; - for (int32 i = 0; authors[i]; i++) { - text << " " << authors[i] << "\n"; + + // Fill in the copyright holder placeholder + text.ReplaceAll("%holder%", copyrightHolder); + + // Add extra copyright strings + if (extraCopyrights != NULL) { + // Add optional extra copyright information + for (int32 i = 0; extraCopyrights[i]; i++) + text << "\n" << B_UTF8_COPYRIGHT << " " << extraCopyrights[i]; } - // The extra information is optional - if (extraInfo != NULL) { - text << "\n" << extraInfo << "\n"; - } + const char* allRightsReserved = B_TRANSLATE_MARK("All Rights Reserved."); + allRightsReserved = gSystemCatalog.GetString(allRightsReserved, + "AboutWindow"); + text << "\n " << allRightsReserved; - fText = new BString(text); -} - - -BAboutWindow::~BAboutWindow() -{ - delete fText; - delete fAppName; + fAboutView->InfoView()->Insert(text.String()); } void -BAboutWindow::Show() +BAboutWindow::AddAuthors(const char** authors) { - const char* aboutTitle = gSystemCatalog.GetString( - B_TRANSLATE_MARK("About" B_UTF8_ELLIPSIS), "AboutWindow"); - const char* closeLabel = gSystemCatalog.GetString( - B_TRANSLATE_MARK("Close"), "AboutWindow"); + if (authors == NULL) + return; - BAlert *alert = new BAlert(aboutTitle, fText->String(), closeLabel); - BTextView *view = alert->TextView(); - BFont font; - view->SetStylable(true); - view->GetFont(&font); - font.SetFace(B_BOLD_FACE); - font.SetSize(font.Size() * 1.7); - view->SetFontAndColor(0, fAppName->Length(), &font); - alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); - alert->Go(); + const char* writtenBy = B_TRANSLATE_MARK("Written by:"); + writtenBy = gSystemCatalog.GetString(writtenBy, "AboutWindow"); + + BString text(""); + if (fAboutView->InfoView()->TextLength() > 0) + text << "\n\n"; + + text << writtenBy; + text << "\n"; + for (int32 i = 0; authors[i]; i++) + text << " " << authors[i] << "\n"; + + fAboutView->InfoView()->Insert(text.String()); } + +void +BAboutWindow::AddSpecialThanks(const char** thanks) +{ + if (thanks == NULL) + return; + + const char* specialThanks = B_TRANSLATE_MARK("Special Thanks:"); + specialThanks = gSystemCatalog.GetString(specialThanks, "AboutWindow"); + + BString text(""); + if (fAboutView->InfoView()->TextLength() > 0) + text << "\n\n"; + + text << specialThanks << "\n"; + for (int32 i = 0; thanks[i]; i++) + text << " " << thanks[i] << "\n"; + + fAboutView->InfoView()->Insert(text.String()); +} + + +void +BAboutWindow::AddVersionHistory(const char** history) +{ + if (history == NULL) + return; + + const char* versionHistory = B_TRANSLATE_MARK("Version history:"); + versionHistory = gSystemCatalog.GetString(versionHistory, "AboutWindow"); + + BString text(""); + if (fAboutView->InfoView()->TextLength() > 0) + text << "\n\n"; + + text << versionHistory << "\n"; + for (int32 i = 0; history[i]; i++) + text << " " << history[i] << "\n"; + + fAboutView->InfoView()->Insert(text.String()); +} + + +void +BAboutWindow::AddExtraInfo(const char* extraInfo) +{ + if (extraInfo == NULL) + return; + + const char* appExtraInfo = B_TRANSLATE_MARK(extraInfo); + appExtraInfo = gSystemCatalog.GetString(extraInfo, "AboutWindow"); + + BString extra(""); + if (fAboutView->InfoView()->TextLength() > 0) + extra << "\n\n"; + + extra << appExtraInfo; + + fAboutView->InfoView()->Insert(extra.String()); +} diff --git a/src/kits/storage/Entry.cpp b/src/kits/storage/Entry.cpp index 7ff8715695..d04038fd38 100644 --- a/src/kits/storage/Entry.cpp +++ b/src/kits/storage/Entry.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009, Haiku Inc. + * Copyright 2002-2012, Haiku Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -191,6 +191,16 @@ BEntry::Exists() const } +const char* +BEntry::Name() const +{ + if (fCStatus != B_OK) + return NULL; + + return fName; +} + + status_t BEntry::SetTo(const BDirectory* dir, const char* path, bool traverse) { @@ -360,18 +370,13 @@ BEntry::GetParent(BDirectory* dir) const status_t BEntry::GetName(char* buffer) const { - status_t result = B_ERROR; + if (fCStatus != B_OK) + return B_NO_INIT; + if (buffer == NULL) + return B_BAD_VALUE; - if (fCStatus != B_OK) { - result = B_NO_INIT; - } else if (buffer == NULL) { - result = B_BAD_VALUE; - } else { - strcpy(buffer, fName); - result = B_OK; - } - - return result; + strcpy(buffer, fName); + return B_OK; } diff --git a/src/preferences/locale/LocalePreflet.cpp b/src/preferences/locale/LocalePreflet.cpp index 5db4bfb600..d71b26be72 100644 --- a/src/preferences/locale/LocalePreflet.cpp +++ b/src/preferences/locale/LocalePreflet.cpp @@ -21,6 +21,7 @@ #define B_TRANSLATION_CONTEXT "Locale Preflet" +const char* kAppName = B_TRANSLATE("Locale"); const char* kSignature = "application/x-vnd.Haiku-Locale"; @@ -29,13 +30,13 @@ class LocalePreflet : public BApplication { LocalePreflet(); virtual ~LocalePreflet(); - virtual void AboutRequested(); virtual void MessageReceived(BMessage* message); private: status_t _RestartApp(const char* signature) const; LocaleWindow* fLocaleWindow; + BAboutWindow* fAboutWindow; }; @@ -44,30 +45,19 @@ private: LocalePreflet::LocalePreflet() : - BApplication(kSignature) + BApplication(kSignature), + fLocaleWindow(new LocaleWindow()), + fAboutWindow(NULL) { - fLocaleWindow = new LocaleWindow(); - fLocaleWindow->Show(); } LocalePreflet::~LocalePreflet() { -} - - -void -LocalePreflet::AboutRequested() -{ - const char* authors[] = { - "Axel Dörfler", - "Adrien Destugues", - "Oliver Tappe", - NULL - }; - BAboutWindow about(B_TRANSLATE("Locale"), 2005, authors); - about.Show(); + // replicant deleted, destroy the about window + if (fAboutWindow != NULL) + fAboutWindow->Quit(); } @@ -81,7 +71,27 @@ LocalePreflet::MessageReceived(BMessage* message) _RestartApp("application/x-vnd.Be-TSKB"); } break; - + + case B_ABOUT_REQUESTED: + if (fAboutWindow == NULL) { + const char* authors[] = { + "Axel Dörfler", + "Adrien Destugues", + "Oliver Tappe", + NULL + }; + + fAboutWindow = new BAboutWindow(kAppName, kSignature); + fAboutWindow->AddCopyright(2005, "Haiku, Inc."); + fAboutWindow->AddAuthors(authors); + fAboutWindow->Show(); + } else if (fAboutWindow->IsHidden()) + fAboutWindow->Show(); + else + fAboutWindow->Activate(); + + break; + default: BApplication::MessageReceived(message); break; diff --git a/src/system/boot/arch/arm/arch_cpu.cpp b/src/system/boot/arch/arm/arch_cpu.cpp index 676191803d..2decd55ab3 100644 --- a/src/system/boot/arch/arm/arch_cpu.cpp +++ b/src/system/boot/arch/arm/arch_cpu.cpp @@ -1,12 +1,11 @@ /* - * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2012, Haiku, Inc. * Distributed under the terms of the MIT License. * - * calculate_cpu_conversion_factor() was written by Travis Geiselbrecht and - * licensed under the NewOS license. + * Authors: + * Ithamar R. Adema */ - #include "cpu.h" #include @@ -17,50 +16,80 @@ #include #include #include - +#include #include - -//#define TRACE_CPU +#define TRACE_CPU #ifdef TRACE_CPU # define TRACE(x) dprintf x #else # define TRACE(x) ; #endif -//uint32 gTimeConversionFactor; - - -static void -calculate_cpu_conversion_factor() -{ - #warning U-Boot:TODO! -} - +/*! check_cpu_features + * + * Please note the fact that ARM7 and ARMv7 are two different things ;) + * ARMx is a specific ARM CPU core instance, while ARMvX refers to the + * ARM architecture specification version.... + * + * Most of the architecture versions we're detecting here we will probably + * never run on, just included for completeness sake... ARMv5 and up are + * the likely ones for us to support (as they all have some kind of MMU). + */ static status_t check_cpu_features() { + uint32 result = 0; + int arch, variant = 0, part = 0, revision = 0, implementor = 0; + + asm volatile("MRC p15, 0, %[c1out], c0, c0, 0":[c1out] "=r" (result)); + + implementor = (result >> 24) & 0xff; + + if (!(result & (1 << 19))) { + switch((result >> 12) & 0xf) { + case 0: /* early ARMv3 or even older */ + arch = ARCH_ARM_PRE_ARM7; + break; + + case 7: /* ARM7 processor */ + arch = (result & (1 << 23)) ? ARCH_ARM_v4T : ARCH_ARM_v3; + variant = (result >> 16) & 0x7f; + part = (result >> 4) & 0xfff; + revision = result & 0xf; + break; + + default: + revision = result & 0xf; + part = (result >> 4) & 0xfff; + switch((result >> 16) & 0xf) { + case 1: arch = ARCH_ARM_v4; break; + case 2: arch = ARCH_ARM_v4T; break; + case 3: arch = ARCH_ARM_v5; break; + case 4: arch = ARCH_ARM_v5T; break; + case 5: arch = ARCH_ARM_v5TE; break; + case 6: arch = ARCH_ARM_v5TEJ; break; + case 7: arch = ARCH_ARM_v6; break; + case 0xf: /* XXX TODO ARMv7 */; break; + } + variant = (result >> 20) & 0xf; + break; + } + } + + TRACE(("%s: implementor=0x%x('%c'), arch=%d, variant=0x%x, part=0x%x, revision=0x%x\n", + __func__, implementor, implementor, arch, variant, part, revision)); - #warning U-Boot:TODO! return B_OK; } - // #pragma mark - - extern "C" void arch_spin(bigtime_t microseconds) { - for(bigtime_t i=0;i 0) { - to[--size] = '\0'; - // copy - for ( ; size; size--, from_length++, to++, from++) { - if ((*to = *from) == '\0') - break; - } - } - // count any leftover from chars - while (*from++ != '\0') - from_length++; - - *faultHandler = oldFaultHandler; - return from_length; - -error: - *faultHandler = oldFaultHandler;*/ - return B_BAD_ADDRESS; -} - - -status_t -arch_cpu_user_memset(void *s, char c, size_t count, addr_t *faultHandler) -{ -#warning WRITEME - -/* - char *xs = (char *)s; - addr_t oldFaultHandler = *faultHandler; - - if (m68k_set_fault_handler(faultHandler, (addr_t)&&error)) - goto error; - - while (count--) - *xs++ = c; - - *faultHandler = oldFaultHandler; - return 0; - -error: - *faultHandler = oldFaultHandler;*/ - - return B_BAD_ADDRESS; -} - - -// The purpose of this function is to trick the compiler. When setting the -// page_handler to a label that is obviously (to the compiler) never used, -// it may reorganize the control flow, so that the labeled part is optimized -// away. -// By invoking the function like this -// -// if (m68k_set_fault_handler(faultHandler, (addr_t)&&error)) -// goto error; -// -// the compiler has to keep the labeled code, since it can't guess the return -// value of this (non-inlinable) function. At least in my tests it worked that -// way, and I hope it will continue to work like this in the future. -// -/*bool -m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler) -{ - *handlerLocation = handler; - return false; -}*/